Category Archives: Linux

Linux related.

Unix dmesg timestamp

Handy script to convert unix’s dmesg timestamp to a human readable format – dmesg_realtime.sh:

1
2
3
4
5
#!/bin/bash
ut=`cut -d' ' -f1 < /proc/uptime`
ts=`date +%s`
realtime_date=`date -d"70-1-1 + $ts sec - $ut sec + $1 sec" +"%F %T"`
echo $realtime_date

Usage:

1
2
3
4
5
6
7
$ dmesg
...
...
[102927.525349] 954929 pages non-shared

$ ./dmesg_realtime.sh 102927.525349
2014-06-17 13:59:17

Amazon RDS Tunnel (Access from your desktop)

If you need to access an Amazon RDS instance locally you can:

  1. Add your IP on the RDS Security Group
  2. Create a tunnel to the RDS

Best chances are you have a dynamic IP address, so you already know that option 1. is a real pain.

You can create a tunnel (2.) by performing the following command on a new terminal window:

1
ssh -l <username> -L 33060:<ec2_rfc_ip>:3306 -N <ext_hostname>

As long as you keep this window open, you’ll be able to access the RDS by connecting to localhost on port 33060:

Nginx SSL configuration for HTTPS and HTTP

The following config will make the domain available both on HTTP and HTTPS protocols:

1
2
3
4
5
6
7
8
9
10
11
12
13
server {
  listen 80;
  listen 443 default ssl;
  #ssl on;  ##### SEE: http://stackoverflow.com/a/8811733/269622
  ssl_certificate /var/www/domain.com/ssl/domain.com.crt;
  ssl_certificate_key /var/www/domain.com/ssl/domain.com.key;

  server_name domain.com;

  root /var/www/domain.com/httpdocs/;

  # ...
}

Give access to /var/log/messages to non-root user

Sometimes while debugging our projects, our developers need to check /var/log/messages for some messages that are being syslogged instead of going to the application logs.

To prevent accidental changes on our servers, developers don’t have root access (that is limited to sys admins) and from time to time sys admins get requests to check /var/log/messages to verify if there are some messages there that could help identify a problem that is occurring.

Using ACLs we were able to give access to /var/log/messages to the ‘users’ group (where all developers belong).

The steps required were:

  • Ensure the filesystems are mounted with acl option.

/etc/fstab was like this before changing:

1
2
3
4
5
6
LABEL=/ / ext4 defaults,noatime 1 1
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
/dev/sda3 none swap sw,comment=cloudconfig 0 0

We need to add acl option after noatime to be:

1
2
3
4
5
6
LABEL=/ / ext4 defaults,noatime,acl 1 1
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
/dev/sda3 none swap sw,comment=cloudconfig 0 0

After doing this change we just need to remount the / filesystem

1
mount -o remount /
  • Give access to the file using ACL for users group
1
/usr/bin/setfacl -m g:users:r /var/log/messages
  • Add a postrotate script to /etc/logrotate.conf to ensure we give the same ACL access after /var/log/messages is rotated. We just need to add the following to /etc/logrotate.conf:
1
2
3
4
# Give access to /var/log/messages to 'users' group after rotate
postrotate
/usr/bin/setfacl -m g:users:r /var/log/messages
endscript

Amazon EC2 – Move a EC2 non-AMI instance to other EC2 region

Amazon EC2 is spread across several regions in the globe (US/Virginia, US/Oregon, US/North California, Europe/Ireland, Asia/Singapore, Asia/Tokyo, Asia Pacific/Sidney, South America/S. Paulo). Some of these regions are very recent (Tokyo, Sidney and also S. Paulo).

To support our Brazil operations we have a set of servers setup on Amazon. Some of them were created prior to the launch of S. Paulo region on Amazon or were created from a Amazon Marketplace image that was not available on S. Paulo region.

We’re in the process of optimizing our infrastructure and it makes sense to move Brazil dedicated servers to S. Paulo region. One of them we had to move from US/Virginia to S.Paulo was a EC2 server based on Ubuntu 12.0.4 LTS (different than the standard image for Amazon EC2, Amazon Machine Image Linux).

Amazon recently released a new feature for EC2 that is key to this process. The new feature is the ability to copy EBS snapshots between regions.

So, to move a Ubuntu 12.0.4 LTS EC2 instance from US/Virginia to South America/S. Paulo you need to:

    -Stop the machine on US/Virginia – only to make sure no changes are done to the filesystem
    -Create a snapshot of the EBS volume attached to the machine on U/Virginia – Go to the Volumes page, identify the volume that is attached to the machine and do the snapshot. If there are multiple volumes attached to the EC2 instance, create a snapshot for each volume. Important: Take note of the size of EC2 instance root volume. It will be required later.
    -On the Snapshot list, for each snapshot that you have created, press “Copy” on the toolbar and select South America/S. Paulo as the destination. This operation may take some time depending on the snapshots size. 10 Gb took less than 30 minutes in our case.
    -Now selecting South America/S.Paulo in the EC2 management console, press “Launch Instance” to create a new EC2 instance and select “Classic Wizard”
    -Choose Ubuntu 12.0.4.x LTS as the type of instance you need (this was the type of our original EC2 instance, it should work with other non-AMI instances).
    -When selecting the root volume type and size, make sure you select the same size as the root volume size of the original instance. Select the key pairs and the availability zone as you wish. Take note of the availability zone where the EC2 machine was launched.
    -When the snapshot that you copied from the original region (root volume) is available on the new region, create a new volume for the snapshot. Make sure you select the same availability zone where the new EC2 instance was created.
    -Stop the new EC2 machine.
    -Go to the volumes list, check the volume that is currently attached to the new instance (this is a completely new volume without the data from the original machine that you want to migrate) and choose “Force detach”
    -Now select the volume you created from the snapshot of the EC2 original machine root volume and attach to the newly created EC2 instance. Choose the same device as the previous volume that was attached (normally /dev/sda1)
    -Create volumes (in the correct availability zone) for the remaining snapshots you want to carry forward from the original machine (in our case, we didn’t have any) and attach to the new machine,.
    -Start the machine on South America/S. Paulo.

Then, don’t forget to update your DNS records and monitoring alert applications (e.g. Nagios) to point to the new IP address of the machine.

SSH connection keeps dropping

I’ve got a shitty internet connection at the moment. While I’m surfing I can barely notice, but the connection itself keeps dropping. As a result, all my SSH connections drop as well.

Here’s the little trick I’me using:

1
ssh -o ServerAliveInterval=30 user@host.com

This will force a “I’m alive” signal every 30 seconds – it is enough to keep me connected!

Additionally, if you want ALL ssh connections to have this option you can edit the ~/.ssh/config file:

1
2
Host *
ServerAliveInterval 30

Some tips on using .htaccess

Imagine you have a website running on http://myserver.com/site1/ and you need to redirect all the traffic to other website that is located on http://someguyserver.com/modules/app/good_app/

The site running on someguyserver.com has the same structure as your site:

  • http://myserver.com/site1/pagina3.html -> http://http://someguyserver.com/modules/app/good_ap/pagina3.html
  • http://myserver.com/site1/hello_world/index.html<7a> -> http://http://someguyserver.com/modules/app/good_ap/hello_world/index.html

    This can be done defining the following rules on the .htaccess file in the root folder of http://myserver.com/site1:

    1
    2
    3
    4
    RewriteEngine on

    ## Redirect the requests to http://myserver.com/site1 into someguyserver.com
    RewriteRule ^(.*)$ http://someguyserver.com/modules/app/good_app/$1 [P]

    The [P] flag is for Proxy which means request will be proxied to the new destination but the user will keep seeing the same URL.

    Now, imagine that all the images, css and javascript on the HTML files inside http://myserver.com/site1/ are being referenced from the root folder like:

    1
    2
    <link rel="stylesheet" type="text/css" media="screen" href="/css/conventional.css" />
    <script type="text/javascript" src="/js/jquery.js"></script>

    This means that our redirect using .htaccess inside the /site1/ directory would not work. To solve this, we need to place a .htaccess file in the root directory of the domain (the directory that serves http://myserver.com) but what if myserver.com is a website itself or has other /site*/ websites that you don’t want to redirect the requests into http://someguyserver.com)?

    This can be done by using a RewriteCond to trigger the RewriteRule. And our RewriteCond can be based on the HTTP_REFERER of the request that will let us know if the request is coming from http://myserver.com or not):

    1
    2
    3
    4
    5
    6
    RewriteEngine on

    ## Requests for css, images or js (/css or /images or /js) that are coming from
    ## http://myserver.com/site1 will be redirected to someguyserver.com
    RewriteCond %{HTTP_REFERER} http://www.myserver.com/site1 [NC]
    RewriteRule ^(css|images|js)/(.*)$ http://www.someguyserver.com/$1/$2 [P]

    If you keep struggling with .htacess files and are not understanding why rules are not being matched and why it is not working, you can enable logging by placing the following in the virtual host configuration for the web site.

    1
    2
    RewriteLog "/var/www/myserver.com/logs/rewrite.log"
    RewriteLogLevel 5

    Note: This requires having MOD_REWRITE installed and enabled on Apache.

  • MySQL kill all queries by user

    Here’s a dirty command-line utility that kills all MySQL queries originated by a given user:

    1
    mysql -u'YOUR_MYSQL_USER' -p'YOUR_MYSQL_PASSWORD' -h'YOUR_MYSQL_HOST' -e "select ID from information_schema.processlist where user='YOUR_MYSQL_USER';" | sed '1d' | awk '{print "kill ", $1, ";"}' | xargs -i mysql -u'YOUR_MYSQL_USER' -p'YOUR_MYSQL_PASSWORD' -h'YOUR_MYSQL_HOST' -e "{}"