Archive for the ‘ Miscellaneous ’ Category

Splunk offers a free version with a 500 MB per day indexing limit, which means you can only add 500 MB amount of new data for indexing per day. This might work for most home users, the only problem is the first time you install Splunk, you might configure it to injest your existing log files which most likely are above 500 MB if you consolidate your logs in a syslog server like I do. In this case, Splunk will stop indexing any data above 500 MB per day. During first time indexing, make sure your existing data or log files are below this limit. If for some reason, you ask Splunk to injest way more than 500 MB of data and you want to start fresh, run the following command to clean up the data –

 splunk  clean eventdata 

You can find the details on Splunk Free on this link.

Here is the series of commands I had to execute to clean up the event data –

[daniel@localhost]$ pwd 
/opt/splunk/bin
[daniel@localhost]$ sudo -H -u splunk ./splunk  clean eventdata
In order to clean, Splunkd must not be running.

[daniel@localhost bin]$ sudo -H -u splunk /opt/splunk/bin/splunk stop
Stopping splunkd...
Shutting down.  Please wait, as this may take a few minutes.
..                                                         [  OK  ]
Stopping splunk helpers...
                                                           [  OK  ]
Done.

[daniel@localhost bin]$ sudo -H -u splunk ./splunk  clean eventdata
This action will permanently erase all events from ALL indexes; it cannot be undone.
Are you sure you want to continue [y/n]? y
Cleaning database _audit.
Cleaning database _blocksignature.
Cleaning database _internal.
Cleaning database _introspection.
Cleaning database _thefishbucket.
Cleaning database history.
Cleaning database main.
Cleaning database summary.
Disabled database 'splunklogger': will not clean.

[daniel@localhost bin]$ sudo -H -u splunk /opt/splunk/bin/splunk start
Checking prerequisites...
	Checking http port [8000]: open
	Checking mgmt port [8089]: open
	Checking appserver port [127.0.0.1:8065]: open
	Checking kvstore port [8191]: open
	Checking configuration...  Done.
	Checking critical directories...	Done
	Checking indexes...
		Validated: _audit _blocksignature _internal _introspection _thefishbucket history main summary
	Done
	Checking filesystem compatibility...  Done
	Checking conf files for problems...
	Done
All preliminary checks passed.

Starting splunk server daemon (splunkd)...  
Done
                                                           [  OK  ]

Waiting for web server at https://127.0.0.1:8000 to be available.. Done


If you get stuck, we're here to help.  
Look for answers here: http://docs.splunk.com

The Splunk web interface is at https://localhost:8000

Eritrean music


All day long, 24/7 Internet streaming radio

Listen to Eritrean Ethiopian Tigrigna music guayla

Listen to Eritrean Ethiopian Tigrigna music


To listen on your smart phone, download the XiiaLive app, VLC media player or any other shoutcast client online internet radio app. After installing the app, search for ‘tigrigna’ or ‘eritrean’ or ‘ethiopian’ and the station is listed as “Eritrean Ethiopian – Tigrigna“.

How do you find out the number of CPU cores available in your Linux system? Here are a number of way, pick the one which works for you –

1. nproc command –

[daniel@kauai tmp]$ nproc
2

2. /proc/cpuinfo

[daniel@kauai tmp]$ grep proc /proc/cpuinfo 
processor	: 0
processor	: 1

3. top – run top command and press ‘1’ (number 1), you will see the list of cores at the top, right below tasks.

Cpu0 : 0.7%us, 0.3%sy, 0.0%ni, 99.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Cpu1 : 2.7%us, 1.0%sy, 0.0%ni, 96.3%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st

4. lscpu – display information about the CPU architecture. Count Sockets times Core(s) per socket, in this case 2 x 1=2 –

[daniel@kauai tmp]$ lscpu 
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                2
On-line CPU(s) list:   0,1
Thread(s) per core:    1
Core(s) per socket:    2
Socket(s):             1
NUMA node(s):          1
Vendor ID:             AuthenticAMD
CPU family:            16
Model:                 6
Model name:            AMD Athlon(tm) II X2 250 Processor
Stepping:              3
CPU MHz:               3000.000
BogoMIPS:              6027.19
Virtualization:        AMD-V
L1d cache:             64K
L1i cache:             64K
L2 cache:              1024K
NUMA node0 CPU(s):     0,1

5. Kernel threads – pick one of the kernel house keeping threads, such as “migration” or “watchdog” and see on how many cores it is running –

[daniel@kauai tmp]$ ps aux |grep '[m]igration'
root         3  0.0  0.0      0     0 ?        S    Dec09   0:02 [migration/0]
root         7  0.0  0.0      0     0 ?        S    Dec09   0:02 [migration/1]

[daniel@kauai tmp]$ ps aux |grep '[w]atchdog'
root         6  0.0  0.0      0     0 ?        S    Dec09   0:00 [watchdog/0]
root        10  0.0  0.0      0     0 ?        S    Dec09   0:00 [watchdog/1]

Sooner or later, you will find yourself adding sensitive data into Ansible playbooks, host or group vars files.Such information might include MySQL DB credentials, AWS secret keys, API credentials etc. Including such sensitive information in plain text might not be acceptable for security compliance reasons or even lead to your systems being owned when your company hires a third party to do pen testing and worst yet by outside hackers. In addition to this, sharing such playbooks to public repositories such as github won’t be easy as you have to manually search and redact all the sensitive information from all your playbooks, and as we know manual procedure is not always error prone. You might ‘forget’ to remove some of the paswords.

One solution for this is a password vault to hold all your sensitive data, and Ansible provides a utitility called ansible-vault to create this encrypted file and the data can be extracted when running your playbooks with a single option. This is equivalent to Chef’s data bag.

In this blog post, I will share with you how to use a secret key file to protect sensitive data in Ansible with ansible-vault utility. The simplest use case is to protect the encrypted file with a password or passphrase, but that is not convinient as you have to type the password everytime you run a playbook and is not as strong as a key file with hundreds or thousands of random characters. Thus the steps below describe only the procedure for setting up a secret key file rather than a password protected encrypted file. Let us get started.

The first step is to generate a key file containing a random list of characters –

#openssl rand -base64 512 |xargs > /opt/ansible/vaultkey

Create or initialize the vault with the key file generated above –

#ansible-vault create --vault-password-file=/opt/ansible/vaultkey /opt/ansible/lamp/group_vars/dbservers.yml

Populate your vault, refer to Ansible documentation on the format of the vault file –

#ansible-vault edit --vault-password-file=/opt/ansible/vaultkey /opt/ansible/lamp/group_vars/dbservers.yml

You can view the contents by replacing ‘edit’ with ‘view’ –

#ansible-vault view --vault-password-file=/opt/ansible/vaultkey /opt/ansible/lamp/group_vars/dbservers.yml

That is it, you have a secret key file to protect and encrypt a YAML file containing all your sensitive variables to be used in your ansible playbooks.

There comes a time though when you have to change the secret key file, say an admin leaves the company after winning the Mega jackbot lottery 🙂 We have to generate a new key file and rekey the encrypted file as soon as possible –

Generate a new key file –

#openssl rand -base64 512 |xargs > /opt/ansible/vaultkey.new

Rekey to new key file –

#ansible-vault rekey --new-vault-password-file=/opt/ansible/vaultkey.new --vault-password-file=/opt/ansible/vaultkey
Rekey successful

Verify –

#ansible-vault view --vault-password-file=/opt/ansible/vaultkey.new /opt/ansible/lamp/group_vars/dbservers.yml

Last but not least, make sure the secret key file is well protected and is readable only by the owner.

#chmod 600 /opt/ansible/vaultkey.new

Finally, you can use the vault with ansible-playbook. In this case, I am running it against site.yml which is a master playbook to setup a LAMP cluster in AWS (pulling the AWS instances using ec2.py dynamic inventory script) –

#ansible-playbook -i /usr/local/bin/ec2.py site.yml --vault-password-file /opt/ansible/vaultkey.new

In Python, you can read from and write to files without import any modules. Python has built-in function “open” which can be used to view and manipulate file objects. Let us see two ways of opening a file for reading/writing, for instance –

   fp_in = open('/etc/hosts', 'r')  # default is 'r', we can omit it.
   fp_out = open('/tmp/hosts', 'w')
   for line in fp_in:
       fp_out.write(line)

   fp_in.close()
   fp_out.close()


   with open('/etc/hosts') as fp_in:
       with open('/tmp/hosts') as fp_out:
       for line in fp_in:
           fp_out.write(line)
   # No need to close file, it is automatically closed at end of block.

One of the most common reasons given why you have to close the file object in the first case is to free up resources. But there is a second reason why you should always use ‘with’ keyword. After writing to a file object, and before closing it, the whole content from the source file might not appear in the destination file. This is because write uses buffering, and the changes will not be reflected until you run flush() or close() on the file object. Here is the help page for ‘write’ –

write(...)
    write(str) -> None.  Write string str to file.
    
    Note that due to buffering, flush() or close() may be needed before
    the file on disk reflects the data written.

Let me demonstrate this by copying the /var/log/messages file to /tmp/message, the bigger the file, the more likely you will witness the effect of buffering. First i will take a copy of /var/log/messages to /var/log/messages.orig, and work with messages.orig as the former will most likely change in size as work along.

[root@kauai ~]# wc -l /var/log/messages.orig 
10544 /var/log/messages.orig

[root@kauai ~]# wc -l /tmp/messages 
10542 /tmp/messages
[root@kauai ~]# tail -1 /tmp/messages 
Nov 16 02:36:02 kauai syslog-ng[1605]: Log statistics; processed='src.internal(s_sys[root@kauai ~]# 

[root@kauai ~]# tail -1 /var/log/messages
Nov 16 02:46:02 kauai syslog-ng[1605]: Log statistics; processed='src.internal(s_sys#2)=1787', stamp='src.internal(s_sys#2)=1416123362', processed='source(s_name_servers)=0', processed='destination(d_mesg)=7693', processed='destination(d_auth)=210', processed='source(s_sys)=12643', processed='global(payload_reallocs)=3568', processed='destination(d_mail)=12', processed='destination(d_kern)=5176', processed='destination(d_mlal)=0', processed='destination(d_ns_filtered)=0', processed='global(msg_clones)=0', processed='destination(d_spol)=0', processed='destination(hosts)=12643', processed='destination(d_boot)=0', processed='global(sdata_updates)=0', processed='center(received)=0', processed='destination(d_cron)=3653', processed='center(queued)=0'

Notice how the destination file /tmp/messages got truncated, it doesn’t even have a newline character at the end.

fp_out.close()
[root@kauai ~]# wc -l /tmp/messages 
10544 /tmp/messages

[root@kauai ~]# tail -1 /var/log/messages
Nov 16 02:56:02 kauai syslog-ng[1605]: Log statistics; processed='src.internal(s_sys#2)=1788', stamp='src.internal(s_sys#2)=1416123962', processed='source(s_name_servers)=0', processed='destination(d_mesg)=7694', processed='destination(d_auth)=211', processed='source(s_sys)=12646', processed='global(payload_reallocs)=3570', processed='destination(d_mail)=12', processed='destination(d_kern)=5176', processed='destination(d_mlal)=0', processed='destination(d_ns_filtered)=0', processed='global(msg_clones)=0', processed='destination(d_spol)=0', processed='destination(hosts)=12646', processed='destination(d_boot)=0', processed='global(sdata_updates)=0', processed='center(received)=0', processed='destination(d_cron)=3654', processed='center(queued)=0'

This problem would not have happened if we had used the ‘with’ keyword, as it automatically does the flush() and close() for us at the end of the block statement –

    with open('/var/log/messages.orig') as fp_in:
    with open('/tmp/messages','w') as fp_out:
        for line in fp_in:
            fp_out.write(line)

[root@kauai ~]# wc -l /var/log/messages.orig 
10544 /var/log/messages.orig
[root@kauai ~]# wc -l /tmp/messages 
10544 /tmp/messages

There you go, both source and destination files synced immediately.

One of the things which confuses many Linux users is why the access time attribute of a file does not change, although the file has been clearly accessed a number of times recently. Let me illustrate here by accessing a file, and checking whether the access time changes or not. I will use

 stat -c %x filename 

to grab the atime attribue.

[root@ip-10-136-87-176 lvm]# sleep 10; date; cat myfile ; stat -c %x myfile
Sun Aug  3 20:56:51 UTC 2014
Beam me up, Scotty.
2014-08-03 20:54:40.000000000 +0000
[root@ip-10-136-87-176 lvm]# sleep 10; date; cat myfile ; stat -c %x myfile
Sun Aug  3 20:57:23 UTC 2014
Beam me up, Scotty.
2014-08-03 20:54:40.000000000 +0000

The atime has not changed. Let us check

/proc/mounts

for any mount options.

[root@ip-10-136-87-176 lvm]# pwd
/mnt/lvm
[root@ip-10-136-87-176 lvm]# grep /mnt/lvm /proc/mounts 
/dev/xvdj1 /mnt/lvm ext3 rw,seclabel,relatime,errors=continue,barrier=1,data=ordered 0 0

The answer to our question lies in the

relatime

option.The Linux Kernel starting from version 2.6.30 switched to using the relatime by default during file system mount. Here is the exerpts from the man page for mount command –

relatime
              Update inode access times relative to modify or change time.  Access time is only updated  if  the
              previous  access time was earlier than the current modify or change time. (Similar to noatime, but
              doesn’t break mutt or other applications that need to know if a file has been read since the  last
              time it was modified.)

              Since  Linux  2.6.30,  the kernel defaults to the behavior provided by this option (unless noatime
              was  specified), and the strictatime option is required to obtain traditional semantics. In  addi-
              tion,  since  Linux 2.6.30, the file’s last access time is always  updated  if  it  is more than 1
              day old.

If the Kernel was to update the atime everytime a file was accessed that would be a big performance killer for disks. Specially in servers with lots of files which are accessed frequently, updating the atime attribute everytime a file is accessed would be a huge I/O burden, that is why the Kernel defaults to relatime. But as always, the Linux Kernel provides you the mechanism to update the atime everytime a file is accessed if you want to. For this to work you can use the

strictatime

option during mount. Let me illustrate this –

[root@ip-10-136-87-176 /]# umount /mnt/lvm
[root@ip-10-136-87-176 /]# mount  -o strictatime /dev/xvdj1 /mnt/lvm/
[root@ip-10-136-87-176 /]# grep '/mnt/lvm' /proc/mounts 
/dev/xvdj1 /mnt/lvm ext3 rw,seclabel,errors=continue,barrier=1,data=ordered 0 0
[root@ip-10-136-87-176 /]# cd /mnt/lvm/
[root@ip-10-136-87-176 lvm]# sleep 10; date; cat myfile ; stat -c %x myfile
Sun Aug  3 21:06:22 UTC 2014
Beam me up, Scotty.
2014-08-03 21:06:22.000000000 +0000
[root@ip-10-136-87-176 lvm]# sleep 60; date; cat myfile ; stat -c %x myfile
Sun Aug  3 21:07:27 UTC 2014
Beam me up, Scotty.
2014-08-03 21:07:27.000000000 +0000

Note: If the file system is mounted with a readonly option, the atime won’t be updated for obvious reasons.