Blocking all BlazingFast IP address blocks (ranges)

Over the past few weeks, I’ve had some issues with my site sometimes not being available or loading very slowly. Checking on the server I could see a high number of Apache processes and a memory usage about 5GB higher than usual. Issuing a netstat I could see that there were many connections from the same IP address: 185.62.189.162.

A whois on this address shows that this IP address belongs to a hosting company in Kiev, Ukraine called BlazingFast. I first blocked this IP address using iptables:

/sbin/iptables -A INPUT -s 185.62.189.162  -j DROP

Since I have a monitoring script checking intrusion attempts and blocking IP addresses, I end up having lots of DROP rules in iptables. So once a week I clean them automatically. Usually hackers do not spend more than a week trying if they see that their traffic to my server is blocked anyway.

Here it was different. As soon as the rules where cleared, it started again with the exact same address. Of course, I immediately blocked this IP address again and sent an email to their abuse email address. But as expected never got an answer. Instead, the same thing happened again but coming from another similar IP address: 185.62.190.221. Whois shows that this address also belongs to the same Ukrainian hosting company.

So, since it was now clear that I’ll keep having problems with IP addresses belonging to this company, I decided to block all traffic coming for the IP ranges owned by them. First I checked what was their ASN on https://who.is/whois-ip/ip-address/185.62.190.221: AS60033. Then looked up their IP address blocks on https://ipinfo.io/AS60033.

Then all I had to do is use iptables to block traffic from these IP address blocks (and make sure that these rules stay in there):

/sbin/iptables -A INPUT -s 185.11.144.0/22 -j DROP
/sbin/iptables -A INPUT -s 185.11.145.0/24 -j DROP
/sbin/iptables -A INPUT -s 185.11.146.0/24 -j DROP
/sbin/iptables -A INPUT -s 185.11.147.0/24 -j DROP
/sbin/iptables -A INPUT -s 185.61.136.0/22 -j DROP
/sbin/iptables -A INPUT -s 185.62.188.0/23 -j DROP
/sbin/iptables -A INPUT -s 185.62.188.0/24 -j DROP
/sbin/iptables -A INPUT -s 185.62.189.0/24 -j DROP
/sbin/iptables -A INPUT -s 185.62.190.0/23 -j DROP
/sbin/iptables -A INPUT -s 185.62.190.0/24 -j DROP
/sbin/iptables -A INPUT -s 185.62.191.0/24 -j DROP
/sbin/iptables -A INPUT -s 188.209.48.0/23 -j DROP
/sbin/iptables -A INPUT -s 188.209.48.0/24 -j DROP
/sbin/iptables -A INPUT -s 188.209.49.0/24 -j DROP
/sbin/iptables -A INPUT -s 188.209.50.0/23 -j DROP
/sbin/iptables -A INPUT -s 188.209.52.0/23 -j DROP
/sbin/iptables -A INPUT -s 188.209.52.0/24 -j DROP
/sbin/iptables -A INPUT -s 188.209.53.0/24 -j DROP

So now the load on the server is fine again and unlike the past few weeks the hosted websites are always accessible and load fast.

It’s interesting to see that BlazingFast is advertizing with the DDOS protection service on hand and actually seem to have customers performing brute force attacks from their servers on the other. If you look up their ASN on the fail2ban reporting service, you will see that a few of their IP addresses are being blocked. So I am not the only one who’s been hit by this. Maybe they should not only focus on protecting their customers from DDOS attacks but should also prevent them from performing attacks.

This post on stackexchange also shows that it’s not something new but it looks like there were already attacks originating from one of their IP addresses in May. The answers to this post will also give you some alternative solutions to block them using the Apache .htaccess file, the Cisco firewall, Nginx, a Microsoft IIS Web Server rule, netsh ADVFirewall or CSF firewall.

I know it’s more difficult to identify attacks originating from one of your IP addresses than attacks targeting your network. As a hosting company, you definitely do not want to have to many false positive and block legitimate traffic created by your customers. But I’m still pretty mad having to waste so much time taking care of this kind of things…

Update 18/07/2015: I’ve ended up also blocking all IP blocks of the following companies: ISPsystem, cjsc and Lekosport-Kharkov LLC which were wasting my time and there’s trying to hack wp-login.php.

Update 20/07/2015: Today I’ve blocked additional IP blocks belonging to Kyivstar PJSC. Slowly I’m starting to think that I’ll have to block access to complete regions in order to be able to sleep at night without worrying…

Linux: ls hangs after NFS connection issues

We noticed today that ls was hanging when run on a particular directory. It didn’t seem to matter which options were used. This directory was not any directory but a directory where NFS shares were mounted.

Checking the output of dmesg, I could also see that there were some issues communicating with the other host:

host2:~ # dmesg
...

[1392590.834500] nfs: server host1 not responding, still trying

...

Then I tried running different commands to try and find out what was working and what was hanging:

host2:~ # cd /home/system/mnt/
host2:/home/system/mnt # ls

was hanging.

host2:~ # cd /home/system/mnt/
host2:/home/system/mnt # df -h .
Filesystem            Size  Used Avail Use% Mounted on
host1:/home         18G  9.3G  7.6G  56% /home

was not hanging. We can also see that the problem is not related to a huge or full share.

host2:~ # cd /home/system/mnt/
host2:/home/system/mnt # cat

pressing tab twice to get the completion was hanging

Also using CTRL-C or CTRL-Z was not working but it was possible to kill the session from another shell:

host2:~ # ps -Af | grep ls
root     19980     1  0 11:27 ?        00:00:00 ls -l /home/system/mnt/
root     22230 22196  0 11:47 pts/8    00:00:00 grep ls
host2:~ # kill -9 19980
host2:~ # ps -Af | grep ls
root     22300 22196  0 11:48 pts/8    00:00:00 grep ls

At some point I figured out that a simple was actually working. It was just hanging because ls was an alias and additional arguments were used. After removing the alias, a normal ls worked but an ls -l was hanging:

host2:~ # alias ls
alias ls='ls $LS_OPTIONS'
host2:~ # cd /home/system/mnt/
host2:/home/system/mnt # unalias ls
host2:/home/system/mnt # alias ls
-bash: alias: ls: not found
host2:/home/system/mnt # ls .
db_bck_add  ext_bck  twiddle.log  upload

Calling ls with strace didn’t show any issue when run without any option:

host2:~ # strace ls /home/system/mnt/
execve("/bin/ls", ["ls", "/home/system/mnt/"], [/* 174 vars */]) = 0
brk(0)                                  = 0x618000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7ffa000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=63299, ...}) = 0
mmap(NULL, 63299, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ffff7fea000
close(3)                                = 0
open("/lib64/librt.so.1", O_RDONLY)     = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340\"\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=47206, ...}) = 0
mmap(NULL, 2132976, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff7bd5000
fadvise64(3, 0, 2132976, POSIX_FADV_WILLNEED) = 0
mprotect(0x7ffff7bdd000, 2093056, PROT_NONE) = 0
mmap(0x7ffff7ddc000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x7000) = 0x7ffff7ddc000
close(3)                                = 0
open("/lib64/libselinux.so.1", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@X\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=113904, ...}) = 0
mmap(NULL, 2213528, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff79b8000
fadvise64(3, 0, 2213528, POSIX_FADV_WILLNEED) = 0
mprotect(0x7ffff79d3000, 2093056, PROT_NONE) = 0
mmap(0x7ffff7bd2000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a000) = 0x7ffff7bd2000
mmap(0x7ffff7bd4000, 1688, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffff7bd4000
close(3)                                = 0
open("/lib64/libacl.so.1", O_RDONLY)    = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\37\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=31464, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7fe9000
mmap(NULL, 2126448, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff77b0000
fadvise64(3, 0, 2126448, POSIX_FADV_WILLNEED) = 0
mprotect(0x7ffff77b7000, 2093056, PROT_NONE) = 0
mmap(0x7ffff79b6000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x7ffff79b6000
close(3)                                = 0
open("/lib64/libc.so.6", O_RDONLY)      = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340\354\1\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1661454, ...}) = 0
mmap(NULL, 3528776, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff7452000
fadvise64(3, 0, 3528776, POSIX_FADV_WILLNEED) = 0
mprotect(0x7ffff75a6000, 2097152, PROT_NONE) = 0
mmap(0x7ffff77a6000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x154000) = 0x7ffff77a6000
mmap(0x7ffff77ab000, 18504, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffff77ab000
close(3)                                = 0
open("/lib64/libpthread.so.0", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@Z\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=135646, ...}) = 0
mmap(NULL, 2212736, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff7235000
fadvise64(3, 0, 2212736, POSIX_FADV_WILLNEED) = 0
mprotect(0x7ffff724c000, 2097152, PROT_NONE) = 0
mmap(0x7ffff744c000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17000) = 0x7ffff744c000
mmap(0x7ffff744e000, 13184, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffff744e000
close(3)                                = 0
open("/lib64/libdl.so.2", O_RDONLY)     = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360\r\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=19114, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7fe8000
mmap(NULL, 2109696, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff7031000
fadvise64(3, 0, 2109696, POSIX_FADV_WILLNEED) = 0
mprotect(0x7ffff7033000, 2097152, PROT_NONE) = 0
mmap(0x7ffff7233000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7ffff7233000
close(3)                                = 0
open("/lib64/libattr.so.1", O_RDONLY)   = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\24\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=18936, ...}) = 0
mmap(NULL, 2113888, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff6e2c000
fadvise64(3, 0, 2113888, POSIX_FADV_WILLNEED) = 0
mprotect(0x7ffff6e30000, 2093056, PROT_NONE) = 0
mmap(0x7ffff702f000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7ffff702f000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7fe7000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7fe5000
arch_prctl(ARCH_SET_FS, 0x7ffff7fe5780) = 0
mprotect(0x7ffff702f000, 4096, PROT_READ) = 0
mprotect(0x7ffff7233000, 4096, PROT_READ) = 0
mprotect(0x7ffff744c000, 4096, PROT_READ) = 0
mprotect(0x7ffff77a6000, 16384, PROT_READ) = 0
mprotect(0x7ffff79b6000, 4096, PROT_READ) = 0
mprotect(0x7ffff7bd2000, 4096, PROT_READ) = 0
mprotect(0x7ffff7ddc000, 4096, PROT_READ) = 0
mprotect(0x616000, 4096, PROT_READ)     = 0
mprotect(0x7ffff7ffc000, 4096, PROT_READ) = 0
munmap(0x7ffff7fea000, 63299)           = 0
set_tid_address(0x7ffff7fe5a50)         = 22807
set_robust_list(0x7ffff7fe5a60, 0x18)   = 0
futex(0x7fffffffd01c, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x7fffffffd01c, 0x189 /* FUTEX_??? */, 1, NULL, 7ffff7fe5780) = -1 EAGAIN (Resource temporarily unavailable)
rt_sigaction(SIGRTMIN, {0x7ffff723a8b0, [], SA_RESTORER|SA_SIGINFO, 0x7ffff72445d0}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {0x7ffff723a940, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x7ffff72445d0}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0
brk(0)                                  = 0x618000
brk(0x639000)                           = 0x639000
open("/etc/selinux/config", O_RDONLY)   = -1 ENOENT (No such file or directory)
statfs("/selinux", {f_type="EXT2_SUPER_MAGIC", f_bsize=4096, f_blocks=3352304, f_bfree=2448097, f_bavail=2277808, f_files=851968, f_ffree=714434, f_fsid={151929686, 1001588022}, f_namelen=255, f_frsize=4096}) = 0
open("/proc/mounts", O_RDONLY)          = 3
fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7ff9000
read(3, "rootfs / rootfs rw 0 0\nudev /dev"..., 1024) = 1024
read(3, "600,retrans=2,sec=sys,mountaddr="..., 1024) = 1024
read(3, "e 0 0\n/dev/sdg1 /db/dump1 ext3 r"..., 1024) = 222
read(3, "", 1024)                       = 0
close(3)                                = 0
munmap(0x7ffff7ff9000, 4096)            = 0
open("/usr/lib/locale/locale-archive", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/locale.alias", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2512, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7ff9000
read(3, "# Locale name alias data base.\n#"..., 4096) = 2512
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0x7ffff7ff9000, 4096)            = 0
open("/usr/lib/locale/en_US.UTF-8/LC_CTYPE", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/en_US.utf8/LC_CTYPE", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=256324, ...}) = 0
mmap(NULL, 256324, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ffff7fa6000
close(3)                                = 0
open("/usr/lib64/gconv/gconv-modules.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=26050, ...}) = 0
mmap(NULL, 26050, PROT_READ, MAP_SHARED, 3, 0) = 0x7ffff7ff3000
close(3)                                = 0
futex(0x7ffff77aaf60, FUTEX_WAKE_PRIVATE, 2147483647) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(1, TIOCGWINSZ, {ws_row=50, ws_col=120, ws_xpixel=0, ws_ypixel=0}) = 0
stat("/home/system/mnt/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("/home/system/mnt/", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
fcntl(3, F_GETFD)                       = 0x1 (flags FD_CLOEXEC)
getdents64(3, /* 6 entries */, 32768)   = 176
getdents64(3, /* 0 entries */, 32768)   = 0
close(3)                                = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 8), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7ff2000
write(1, "db_bck_add  ext_bck  twiddle.log"..., 41db_bck_add  ext_bck  twiddle.log  upload
) = 41
close(1)                                = 0
munmap(0x7ffff7ff2000, 4096)            = 0
close(2)                                = 0
exit_group(0)                           = ?
s

But run with the -l option, it was hanging and I could see which entry was causing this:

host2:~ # strace ls -l /home/system/mnt/
execve("/bin/ls", ["ls", "-l", "/home/system/mnt/"], [/* 174 vars */]) = 0
brk(0)                                  = 0x618000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7ffa000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=63299, ...}) = 0
mmap(NULL, 63299, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ffff7fea000
close(3)                                = 0
open("/lib64/librt.so.1", O_RDONLY)     = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340\"\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=47206, ...}) = 0
mmap(NULL, 2132976, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff7bd5000
fadvise64(3, 0, 2132976, POSIX_FADV_WILLNEED) = 0
mprotect(0x7ffff7bdd000, 2093056, PROT_NONE) = 0
mmap(0x7ffff7ddc000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x7000) = 0x7ffff7ddc000
close(3)                                = 0
open("/lib64/libselinux.so.1", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@X\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=113904, ...}) = 0
mmap(NULL, 2213528, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff79b8000
fadvise64(3, 0, 2213528, POSIX_FADV_WILLNEED) = 0
mprotect(0x7ffff79d3000, 2093056, PROT_NONE) = 0
mmap(0x7ffff7bd2000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a000) = 0x7ffff7bd2000
mmap(0x7ffff7bd4000, 1688, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffff7bd4000
close(3)                                = 0
open("/lib64/libacl.so.1", O_RDONLY)    = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\37\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=31464, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7fe9000
mmap(NULL, 2126448, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff77b0000
fadvise64(3, 0, 2126448, POSIX_FADV_WILLNEED) = 0
mprotect(0x7ffff77b7000, 2093056, PROT_NONE) = 0
mmap(0x7ffff79b6000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x7ffff79b6000
close(3)                                = 0
open("/lib64/libc.so.6", O_RDONLY)      = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340\354\1\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1661454, ...}) = 0
mmap(NULL, 3528776, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff7452000
fadvise64(3, 0, 3528776, POSIX_FADV_WILLNEED) = 0
mprotect(0x7ffff75a6000, 2097152, PROT_NONE) = 0
mmap(0x7ffff77a6000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x154000) = 0x7ffff77a6000
mmap(0x7ffff77ab000, 18504, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffff77ab000
close(3)                                = 0
open("/lib64/libpthread.so.0", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@Z\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=135646, ...}) = 0
mmap(NULL, 2212736, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff7235000
fadvise64(3, 0, 2212736, POSIX_FADV_WILLNEED) = 0
mprotect(0x7ffff724c000, 2097152, PROT_NONE) = 0
mmap(0x7ffff744c000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17000) = 0x7ffff744c000
mmap(0x7ffff744e000, 13184, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7ffff744e000
close(3)                                = 0
open("/lib64/libdl.so.2", O_RDONLY)     = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360\r\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=19114, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7fe8000
mmap(NULL, 2109696, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff7031000
fadvise64(3, 0, 2109696, POSIX_FADV_WILLNEED) = 0
mprotect(0x7ffff7033000, 2097152, PROT_NONE) = 0
mmap(0x7ffff7233000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7ffff7233000
close(3)                                = 0
open("/lib64/libattr.so.1", O_RDONLY)   = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\24\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=18936, ...}) = 0
mmap(NULL, 2113888, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7ffff6e2c000
fadvise64(3, 0, 2113888, POSIX_FADV_WILLNEED) = 0
mprotect(0x7ffff6e30000, 2093056, PROT_NONE) = 0
mmap(0x7ffff702f000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x3000) = 0x7ffff702f000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7fe7000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7fe5000
arch_prctl(ARCH_SET_FS, 0x7ffff7fe5780) = 0
mprotect(0x7ffff702f000, 4096, PROT_READ) = 0
mprotect(0x7ffff7233000, 4096, PROT_READ) = 0
mprotect(0x7ffff744c000, 4096, PROT_READ) = 0
mprotect(0x7ffff77a6000, 16384, PROT_READ) = 0
mprotect(0x7ffff79b6000, 4096, PROT_READ) = 0
mprotect(0x7ffff7bd2000, 4096, PROT_READ) = 0
mprotect(0x7ffff7ddc000, 4096, PROT_READ) = 0
mprotect(0x616000, 4096, PROT_READ)     = 0
mprotect(0x7ffff7ffc000, 4096, PROT_READ) = 0
munmap(0x7ffff7fea000, 63299)           = 0
set_tid_address(0x7ffff7fe5a50)         = 22977
set_robust_list(0x7ffff7fe5a60, 0x18)   = 0
futex(0x7fffffffd00c, FUTEX_WAKE_PRIVATE, 1) = 0
futex(0x7fffffffd00c, 0x189 /* FUTEX_??? */, 1, NULL, 7ffff7fe5780) = -1 EAGAIN (Resource temporarily unavailable)
rt_sigaction(SIGRTMIN, {0x7ffff723a8b0, [], SA_RESTORER|SA_SIGINFO, 0x7ffff72445d0}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {0x7ffff723a940, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x7ffff72445d0}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM_INFINITY}) = 0
brk(0)                                  = 0x618000
brk(0x639000)                           = 0x639000
open("/etc/selinux/config", O_RDONLY)   = -1 ENOENT (No such file or directory)
statfs("/selinux", {f_type="EXT2_SUPER_MAGIC", f_bsize=4096, f_blocks=3352304, f_bfree=2448097, f_bavail=2277808, f_file                                                                                        s=851968, f_ffree=714434, f_fsid={151929686, 1001588022}, f_namelen=255, f_frsize=4096}) = 0
open("/proc/mounts", O_RDONLY)          = 3
fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7ff9000
read(3, "rootfs / rootfs rw 0 0\nudev /dev"..., 1024) = 1024
read(3, "600,retrans=2,sec=sys,mountaddr="..., 1024) = 1024
read(3, "e 0 0\n/dev/sdg1 /db/dump1 ext3 r"..., 1024) = 222
read(3, "", 1024)                       = 0
close(3)                                = 0
munmap(0x7ffff7ff9000, 4096)            = 0
open("/usr/lib/locale/locale-archive", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/locale.alias", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2512, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7ffff7ff9000
read(3, "# Locale name alias data base.\n#"..., 4096) = 2512
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0x7ffff7ff9000, 4096)            = 0
open("/usr/lib/locale/en_US.UTF-8/LC_CTYPE", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/en_US.utf8/LC_CTYPE", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=256324, ...}) = 0
mmap(NULL, 256324, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7ffff7fa6000
close(3)                                = 0
open("/usr/lib64/gconv/gconv-modules.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=26050, ...}) = 0
mmap(NULL, 26050, PROT_READ, MAP_SHARED, 3, 0) = 0x7ffff7ff3000
close(3)                                = 0
futex(0x7ffff77aaf60, FUTEX_WAKE_PRIVATE, 2147483647) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(1, TIOCGWINSZ, {ws_row=50, ws_col=120, ws_xpixel=0, ws_ypixel=0}) = 0
lstat("/home/system/mnt/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lgetxattr("/home/system/mnt/", "security.selinux", 0x61e400, 255) = -1 EOPNOTSUPP (Operation not supported)
getxattr("/home/system/mnt/", "system.posix_acl_access", 0x0, 0) = -1 ENODATA (No data available)
getxattr("/home/system/mnt/", "system.posix_acl_default", 0x0, 0) = -1 ENODATA (No data available)
socket(PF_FILE, 0x80801 /* SOCK_??? */, 0) = 3
connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = 0
sendto(3, "\2\0\0\0\v\0\0\0\7\0\0\0passwd\0", 19, MSG_NOSIGNAL, NULL, 0) = 19
poll([{fd=3, events=POLLIN|POLLERR|POLLHUP}], 1, 5000) = 1 ([{fd=3, revents=POLLIN|POLLHUP}])
recvmsg(3, {msg_name(0)=NULL, msg_iov(2)=[{"passwd\0", 7}, {"\270O\3\0\0\0\0\0", 8}], msg_controllen=24, {cmsg_len=20, c                                                                                        msg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS, {4}}, msg_flags=MSG_CMSG_CLOEXEC}, MSG_CMSG_CLOEXEC) = 15
mmap(NULL, 217016, PROT_READ, MAP_SHARED, 4, 0) = 0x7ffff7f71000
close(4)                                = 0
close(3)                                = 0
socket(PF_FILE, 0x80801 /* SOCK_??? */, 0) = 3
connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = 0
sendto(3, "\2\0\0\0\f\0\0\0\6\0\0\0group\0", 18, MSG_NOSIGNAL, NULL, 0) = 18
poll([{fd=3, events=POLLIN|POLLERR|POLLHUP}], 1, 5000) = 1 ([{fd=3, revents=POLLIN|POLLHUP}])
recvmsg(3, {msg_name(0)=NULL, msg_iov(2)=[{"group\0", 6}, {"\270O\3\0\0\0\0\0", 8}], msg_controllen=24, {cmsg_len=20, cm                                                                                        sg_level=SOL_SOCKET, cmsg_type=SCM_RIGHTS, {4}}, msg_flags=MSG_CMSG_CLOEXEC}, MSG_CMSG_CLOEXEC) = 14
mmap(NULL, 217016, PROT_READ, MAP_SHARED, 4, 0) = 0x7ffff7f3c000
close(4)                                = 0
close(3)                                = 0
open("/home/system/mnt/", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3
fcntl(3, F_GETFD)                       = 0x1 (flags FD_CLOEXEC)
getdents64(3, /* 6 entries */, 32768)   = 176
lstat("/home/system/mnt/db_bck_add",

The directory on which it was hanging is itself an NFS share mounted on the other host. This share had some problem and had to be unmounted and remounted. It looks like this caused the NFS connection to hang for some reason. NFS seems to be an extremely fragile filesystem and if either your network or  the server itself are not 100% stable, you have a problem.

So the summary is that a reboot solves this issue and I at least figured out how to identify which of the directory contents was causing the issue. Unfortunately, not much more… If this happens again and I find out how to further investigate this or whether a restart of the NFS service is enough to solve the issue (without reboot), I’ll update this post.

 

Linux: Check the glibc version

If you need to check which version of the GNU C library (glibc) is used on you Linux system, whether it’s to check whether you are affected by the GHOST vulnerability or you need to install a software requiring at least a certain version but not checking it on build/installation, the easiest way is to use ldd which comes with glibc and should in most cases have the same version:

> ldd --version
ldd (GNU libc) 2.11.1

If you know you might have patched the system to use a different version of ldd and know that its version doesn’t match the glibc version, you have two additional ways to find out the glibc version:

  1. Check the version of the installed glibc rpm package
  2. Check the version of the used libc.so file

First using rpm:

> rpm -q glibc
glibc-2.11.1-0.17.4

The second way is a little bit more difficult. You first have to find which libc.so file is being used by a known program e.g. netstat:

> ldd `which netstat`
        linux-vdso.so.1 =>  (0x00007ffff7ffb000)
        libc.so.6 => /lib64/libc.so.6 (0x00007ffff7a80000)
        /lib64/ld-linux-x86-64.so.2 (0x00007ffff7dde000)

You can also find the libc.so file used with the following command:

> cat `gcc -print-file-name=libc.so`
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a  AS_NEEDED ( /lib64/ld-linux-x86-64.so.2 ) )

So we now know that /lib64/libc.so.6 is being used and we just need to get it’s version:

> /lib64/libc.so.6 --version
GNU C Library stable release version 2.11.1 (20100118), by Roland McGrath et al.
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Configured for x86_64-suse-linux.
Compiled by GNU CC version 4.3.4 [gcc-4_3-branch revision 152973].
Compiled on a Linux 2.6.32 system on 2010-05-06.
Available extensions:
        crypt add-on version 2.1 by Michael Glad and others
        GNU Libidn by Simon Josefsson
        Native POSIX Threads Library by Ulrich Drepper et al
        BIND-8.2.3-T5B
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.

If you want to determine the glibc version from C program and not from a shell script, you can just use something like this:

#include <stdio.h>
#include <stdlib.h>
#include <gnu/libc-version.h>

int main(int argc, char *argv[]) {
  printf("glibc version: %s\n", gnu_get_libc_version());
}

You can then compile it and execute it like this to get the glibc version:

> gcc glibc_version.c -o glibc_version
> ./glibc_version
glibc version: 2.11.1

Of course, if your C file is not called glibc_version.c, you’ll have to use the name you’ve actually used in the gcc arguments.

Since your current shell is probably also using glibc, you can also find out which libc library it has loaded by using the following command:

> lsof -p $$ | grep libc
bash    9177 root  mem    REG    8,2  1661454 827401 /lib64/libc-2.11.1.so

Of course there may be systems where the file name itself doesn’t give you the glibc version but just as shown above with /lib64/libc.so.6 you can call the so file with the –version to get its version information e.g.:

lsof -p $$ | grep libc | awk ' { print $NF" --version"; } ' | sh
GNU C Library stable release version 2.11.1 (20100118), by Roland McGrath et al.
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Configured for x86_64-suse-linux.
Compiled by GNU CC version 4.3.4 [gcc-4_3-branch revision 152973].
Compiled on a Linux 2.6.32 system on 2010-05-06.
Available extensions:
        crypt add-on version 2.1 by Michael Glad and others
        GNU Libidn by Simon Josefsson
        Native POSIX Threads Library by Ulrich Drepper et al
        BIND-8.2.3-T5B
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.

 

Debian / Ubuntu: viewing the apt change log

I am running rkhunter as a cron job and thus receiving notification any time I’ve installed something. Ideally I should be checking the output immediately and updating its database if it is just reporting a change due to a software update I’ve performed. But very often I don’t have time to do it right away and end up forgetting for days. At some point in time, I do check the logs and see that some pieces of software have been changed. By that time I usually do not remember what packages I’ve updated since last rkhunter database update. So I needed a way to check the history of installation of packages.

The bad news is that there is no apt-history command which would easily display the history of installed, updated and removed packages. The good news is that there are some log files which contain the whole history and can be used as a basis to extract this information.

There are actually two location where you can find such log files:

  • /var/log/apt/history.log* –> This contains the apt history logs
  • /var/log/dpkg.log* –> This contains the dpkg logs

Note that older log files are compressed with gzip. For the apt history logs, only the latest file is uncompressed. For the dpkg logs, the two latest files are uncompressed. Luckily, you can use the -f option of zcat to output the contents of those log files, no matter whether they are compressed or not. And combining it with ls -tr you can basically decompress them and concatenate them on the fly in the proper order:

zcat -f $(ls -tr /var/log/apt/history.log*)
zcat -f $(ls -tr /var/log/dpkg.log*)

Before we start, I wanted to mention that I do know that aptitude also writes a log file (/var/log/aptitude) but when I looked at it, it only contained information about what happened in the past 8 days. So it wasn’t really useful for my purpose. There is probably a way to configure aptitude to store more history in there but since I found another good solution, let’s stick to this… Also if you use Synaptic, there is also a “View History” function in the GUI. But it only shows changes made with Synaptic, not from the command line or automatically e.g. by Plesk auto-installer.

First I had a look at the contents of the apt history log files. It looks like this:

Start-Date: 2014-02-17  21:53:00
Install: libserf1:amd64 (1.3.4-1+WANdisco, automatic), php5-imagick:amd64 (3.1.0~rc1-1+b2, automatic), php5-pgsql:amd64 (5.4.4-14+deb7u7, automatic), php5-mcrypt:amd64 (5.4.4-14+deb7u7, automatic), php5-intl:amd64 (5.4.4-14+deb7u7, automatic)
Upgrade: owncloud:amd64 (5.0.13-1, 6.0.1-1), subversion:amd64 (1.7.13-1+WANdisco, 1.7.14-1+WANdisco), libsvn1:amd64 (1.7.13-1+WANdisco, 1.7.14-1+WANdisco), libapache2-svn:amd64 (1.7.13-1+WANdisco, 1.7.14-1+WANdisco)
End-Date: 2014-02-17  21:53:20

Processing it with Unix tools is possible but it is a pain because you have to consider groups of lines, between a Start-Date and an End-Date, and the number of lines inbetween is not always the same (potentially one line for installs, one line for upgrades and one line for removals). This can of course be procesed with some grep, awk, sed and other utilities. But this has two problems: first I’m lazy, second if the command is too complex I will never remember it even if I use it daily.

So I decided to have a look at the dpkg log files and see whether they were friendlier:

2014-02-17 21:53:00 startup archives unpack
2014-02-17 21:53:00 install libserf1:amd64  1.3.4-1+WANdisco
2014-02-17 21:53:00 status half-installed libserf1:amd64 1.3.4-1+WANdisco
2014-02-17 21:53:00 status unpacked libserf1:amd64 1.3.4-1+WANdisco
2014-02-17 21:53:00 status unpacked libserf1:amd64 1.3.4-1+WANdisco
2014-02-17 21:53:01 install php5-intl:amd64  5.4.4-14+deb7u7
2014-02-17 21:53:01 status triggers-pending libapache2-mod-php5:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:01 status not-installed php5-intl:amd64 
2014-02-17 21:53:01 status half-installed php5-intl:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:01 status unpacked php5-intl:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:01 status unpacked php5-intl:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:02 install php5-mcrypt:amd64  5.4.4-14+deb7u7
2014-02-17 21:53:02 status not-installed php5-mcrypt:amd64 
2014-02-17 21:53:02 status half-installed php5-mcrypt:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:02 status unpacked php5-mcrypt:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:02 status unpacked php5-mcrypt:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:02 install php5-pgsql:amd64  5.4.4-14+deb7u7
2014-02-17 21:53:02 status not-installed php5-pgsql:amd64 
2014-02-17 21:53:02 status half-installed php5-pgsql:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:03 status unpacked php5-pgsql:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:03 status unpacked php5-pgsql:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:03 upgrade subversion:amd64 1.7.13-1+WANdisco 1.7.14-1+WANdisco
2014-02-17 21:53:03 status half-configured subversion:amd64 1.7.13-1+WANdisco
2014-02-17 21:53:03 status unpacked subversion:amd64 1.7.13-1+WANdisco
2014-02-17 21:53:03 status half-installed subversion:amd64 1.7.13-1+WANdisco
2014-02-17 21:53:03 status triggers-pending man-db:amd64 2.6.2-1
2014-02-17 21:53:04 status half-installed subversion:amd64 1.7.13-1+WANdisco
2014-02-17 21:53:04 status half-installed subversion:amd64 1.7.13-1+WANdisco
2014-02-17 21:53:04 status unpacked subversion:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:04 status unpacked subversion:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:04 upgrade libsvn1:amd64 1.7.13-1+WANdisco 1.7.14-1+WANdisco
2014-02-17 21:53:04 status half-configured libsvn1:amd64 1.7.13-1+WANdisco
2014-02-17 21:53:04 status unpacked libsvn1:amd64 1.7.13-1+WANdisco
2014-02-17 21:53:04 status half-installed libsvn1:amd64 1.7.13-1+WANdisco
2014-02-17 21:53:05 status half-installed libsvn1:amd64 1.7.13-1+WANdisco
2014-02-17 21:53:05 status unpacked libsvn1:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:05 status unpacked libsvn1:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:05 upgrade libapache2-svn:amd64 1.7.13-1+WANdisco 1.7.14-1+WANdisco
2014-02-17 21:53:05 status half-configured libapache2-svn:amd64 1.7.13-1+WANdisco
2014-02-17 21:53:05 status unpacked libapache2-svn:amd64 1.7.13-1+WANdisco
2014-02-17 21:53:05 status half-installed libapache2-svn:amd64 1.7.13-1+WANdisco
2014-02-17 21:53:05 status half-installed libapache2-svn:amd64 1.7.13-1+WANdisco
2014-02-17 21:53:05 status unpacked libapache2-svn:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:05 status unpacked libapache2-svn:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:06 upgrade owncloud:all 5.0.13-1 6.0.1-1
2014-02-17 21:53:06 status half-configured owncloud:all 5.0.13-1
2014-02-17 21:53:06 status unpacked owncloud:all 5.0.13-1
2014-02-17 21:53:06 status half-installed owncloud:all 5.0.13-1
2014-02-17 21:53:11 status half-installed owncloud:all 5.0.13-1
2014-02-17 21:53:11 status unpacked owncloud:all 6.0.1-1
2014-02-17 21:53:11 status unpacked owncloud:all 6.0.1-1
2014-02-17 21:53:12 install php5-imagick:amd64  3.1.0~rc1-1+b2
2014-02-17 21:53:12 status half-installed php5-imagick:amd64 3.1.0~rc1-1+b2
2014-02-17 21:53:12 status unpacked php5-imagick:amd64 3.1.0~rc1-1+b2
2014-02-17 21:53:12 status unpacked php5-imagick:amd64 3.1.0~rc1-1+b2
2014-02-17 21:53:12 trigproc libapache2-mod-php5:amd64 5.4.4-14+deb7u7 5.4.4-14+deb7u7
2014-02-17 21:53:12 status half-configured libapache2-mod-php5:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:12 status installed libapache2-mod-php5:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:13 trigproc man-db:amd64 2.6.2-1 2.6.2-1
2014-02-17 21:53:13 status half-configured man-db:amd64 2.6.2-1
2014-02-17 21:53:13 status installed man-db:amd64 2.6.2-1
2014-02-17 21:53:14 startup packages configure
2014-02-17 21:53:14 configure libserf1:amd64 1.3.4-1+WANdisco 
2014-02-17 21:53:14 status unpacked libserf1:amd64 1.3.4-1+WANdisco
2014-02-17 21:53:14 status half-configured libserf1:amd64 1.3.4-1+WANdisco
2014-02-17 21:53:14 status installed libserf1:amd64 1.3.4-1+WANdisco
2014-02-17 21:53:14 configure php5-intl:amd64 5.4.4-14+deb7u7 
2014-02-17 21:53:14 status triggers-pending libapache2-mod-php5:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:14 status unpacked php5-intl:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:15 status unpacked php5-intl:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:15 status half-configured php5-intl:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:15 status triggers-awaited php5-intl:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:15 configure php5-mcrypt:amd64 5.4.4-14+deb7u7 
2014-02-17 21:53:15 status unpacked php5-mcrypt:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:15 status unpacked php5-mcrypt:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:15 status half-configured php5-mcrypt:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:16 status triggers-awaited php5-mcrypt:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:16 configure php5-pgsql:amd64 5.4.4-14+deb7u7 
2014-02-17 21:53:16 status unpacked php5-pgsql:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:16 status unpacked php5-pgsql:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:16 status half-configured php5-pgsql:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:17 status triggers-awaited php5-pgsql:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:17 configure php5-imagick:amd64 3.1.0~rc1-1+b2 
2014-02-17 21:53:17 status unpacked php5-imagick:amd64 3.1.0~rc1-1+b2
2014-02-17 21:53:17 status half-configured php5-imagick:amd64 3.1.0~rc1-1+b2
2014-02-17 21:53:18 status installed php5-imagick:amd64 3.1.0~rc1-1+b2
2014-02-17 21:53:18 trigproc libapache2-mod-php5:amd64 5.4.4-14+deb7u7 
2014-02-17 21:53:18 status half-configured libapache2-mod-php5:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:18 status installed php5-pgsql:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:18 status installed php5-mcrypt:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:18 status installed php5-intl:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:18 status installed libapache2-mod-php5:amd64 5.4.4-14+deb7u7
2014-02-17 21:53:18 configure owncloud:all 6.0.1-1 
2014-02-17 21:53:18 status unpacked owncloud:all 6.0.1-1
2014-02-17 21:53:19 status unpacked owncloud:all 6.0.1-1
2014-02-17 21:53:19 status unpacked owncloud:all 6.0.1-1
2014-02-17 21:53:19 status half-configured owncloud:all 6.0.1-1
2014-02-17 21:53:19 status installed owncloud:all 6.0.1-1
2014-02-17 21:53:19 configure subversion:amd64 1.7.14-1+WANdisco 
2014-02-17 21:53:19 status unpacked subversion:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:19 status unpacked subversion:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:19 status unpacked subversion:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:19 status unpacked subversion:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:19 status half-configured subversion:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:19 status installed subversion:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:19 configure libsvn1:amd64 1.7.14-1+WANdisco 
2014-02-17 21:53:19 status unpacked libsvn1:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:19 status half-configured libsvn1:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:19 status installed libsvn1:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:20 configure libapache2-svn:amd64 1.7.14-1+WANdisco 
2014-02-17 21:53:20 status unpacked libapache2-svn:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:20 status unpacked libapache2-svn:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:20 status unpacked libapache2-svn:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:20 status half-configured libapache2-svn:amd64 1.7.14-1+WANdisco
2014-02-17 21:53:20 status installed libapache2-svn:amd64 1.7.14-1+WANdisco

It’s much more verbose but each line contains both the date and time and what was performed. All you need to do is use a grep to extract the information you need. So depending what you’re after you’ll use one of these 3 commands:

zcat -f $(ls -tr /var/log/dpkg.log*) | grep " install "
zcat -f $(ls -tr /var/log/dpkg.log*) | grep " upgrade "
zcat -f $(ls -tr /var/log/dpkg.log*) | grep " remove "

You will then see something like this:

# zcat -f $(ls -tr /var/log/dpkg.log*) | grep " remove "
2014-12-01 18:43:15 remove libneon27-gnutls:amd64 0.29.6-3 <keine>
2014-12-01 18:43:16 remove libnss3-1d:amd64 2:3.14.5-1+deb7u3 <keine>
2014-12-01 18:43:16 remove libtommath0:amd64 0.42.0-1 <keine>

Note that keine means “none” in German, so removing a package is going from a certain version to none.

Debian/Ubuntu: The following packages have been kept back

Note that for all commands below, you might need to add a leading sudo depending on your system.

When updating your packages using apt-get, you might get the following message:

# apt-get upgrade
Building Dependency Tree… Done
The following packages have been kept back:
xxxxxx xxxxxx xxxxxx xxxxxx
0 upgraded, 0 newly installed, 0 to remove and 4 not upgraded.

This means that there are packages which can be updated but they were not. So what are the reasons why some packages wouldn’t be updated ?

First let’s look at what apt-get upgrade does:

apt-get upgrade installs the newest versions of all packages which are already installed on the system from the configured sources. What apt-get upgrade doesn’t do is install additional packages or remove existing ones. The fact that it doesn’t install new packages is the reason why your packages are being kept back. These packages have an updated list of dependencies and apt-get would need to install new packages in order to install the new version of the software.

So what can you do about it ? There are basically 3 ways to handle it.

dist-upgrade

The first one is to use dist-upgrade. apt-get dist-upgrade does basically the same as upgrade. But additionally, it removes and installs packages in order to accommodate the updated list of dependencies of newer versions of the install packages.

When using diet-upgrade, you will be presented with a list of changes which will be applied. There will be a list of packages being additionally installed and a list of packages which will be removed.

You have to especially pay attention to the list of packages to be removed. In the list of packages to be removed, you will not only find packages being removed because they are not needed anymore but also packages which will be removed because they are not compatible with the latest version of the packages you are updating.

On my system, this is very often the case for Plesk which tends to force me to keep outdated packages for a little longer. Forcing an update of these packages would result in Plesk being uninstalled. Recovering from this is not very easy… Also, if you install beta versions of some software, you might also end up getting long list of packages to be removed because they would not be compatible anymore.

Also, you might in some cases have packages required by others but not cleanly listed as a dependency (once had this problem with subversion).

install

If you want to have the required packages installed but do not want to have packages removed, you can use apt install:

apt-get install <list of packages>

This will first resolve the kept-back dependencies and will offer to install additionally required packages.

aptitude

Start aptitude, select the list of upgradable packages, press “g” twice to install.

Then answer the questions and follow the instructions.

Still problems?

If all of this doesn’t work, you may want to give some of the following a try. These are various things I’ve needed in some cases to get rid of conflicts using apt-get.

Reinstalling the packages kept back:

apt-get install --reinstall <list of packages>

Checking for a given package, the installed and the versions available from the configured sources:

apt-cache policy <package name>

Use aptitude instead of apt-get:

aptitude update && aptitude upgrade

Use aptitude safe-upgrade to upgrade currently installed packages as well as install new packages to resolve new dependencies, but without removing installed packages:

aptitude safe-upgrade

 

Switching to user root

Why switch to root ?

When in a shell as a non-root user, you have to use sudo to execute a command which requires root privileges e.g.:

sudo chown henribenoit:_www *

That’s the clean way of doing it: use a non-root user and only use sudo when required. But sometimes it just drives me crazy to prefix most commands with a sudo and I’d just rather switch to the root user, do all I need to do and then switch back.

The alternatives

There are a couple of ways to do this:

  • sudo -i
  • sudo su
  • sudo -s
  • sudo bash

All of them will allow you to switch to the root user but give you an environment more or less mixed with the previous user’s environment. Let’s see what each of these commands actually does.

In the sections below, I’ll execute the following command after switching to root with the respective commands:

env | grep "SHELL=
USER=
PATH=
PWD=
HOME=" | grep -v OLDPWD | sort -u

When running it before switching to root, I do get:

HOME=/Users/henribenoit
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/henribenoit
PWD=/Library/WebServer/Documents
SHELL=/bin/bash
TESTPWD=/tmp
USER=henribenoit

Note that I’ve updated the PATH adding the directory /Users/henribenoit to check whether the PATH is being reset and I’ve also added a dummy environment variable TESTPWD to check whether it’s still in there after switching to root. I made these 2 changes executing the following:

export PATH=$PATH:/Users/henribenoit
export TESTPWD=/tmp

sudo -i

Of all four options, sudo -i is the one which will give you the purest environment.

Running the command above, you will get:

HOME=/var/root
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/henribenoit
PWD=/var/root
SHELL=/bin/sh
SUDO_USER=henribenoit
USER=root

So it did take over the PATH I had defined before switching users but changed the home directory, the current directory, the shell used and the current user. Also the additional dummy variable was not taken over.

sudo su

Running the command above after using sudo su, returns the following:

HOME=/var/root
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/henribenoit
PWD=/Users/henribenoit
SHELL=/bin/sh
SUDO_USER=henribenoit
USER=root

Here the PATH and the current directory were not changed after switching to root. The rest was changed and the dummy variable is also not present anymore.

So the difference between sudo -i and sudo su seems to be that sudo -i additionally changes the current directory.

sudo -s

This command takes over even more of the environment before the user switch:

HOME=/Users/henribenoit
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/henribenoit
PWD=/Users/henribenoit
SHELL=/bin/bash
SUDO_USER=henribenoit
USER=root

So the home directory, the path, the current directory and the shell did not change after using sudo -s. So only the current user was changed to root and the dummy variable is not available anymore.

The difference between sudo su and sudo -s is that the latter does not change the shell and home directory.

sudo bash

This one gives you the exact same environment as the previous one:

HOME=/Users/henribenoit
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/henribenoit
PWD=/Users/henribenoit
SHELL=/bin/bash
SUDO_USER=henribenoit
USER=root

Even if you check all variables returned by env, you will see that there is no difference.

Which one to use ?

As always, it depends on what you will do after switching to root.

Changing the home folder will:

  • change the command history you are accessing
  • have an impact on some program installers

I usually do not have an issue with installers referencing the HOME directory. But in some cases I find it useful to keep the history I had with the previous user. In this case, I rather go for sudo -s or sudo bash.

Obviously using a different shell will force you to potentially use a different syntax. That’s why I only use sudo su if I need to the HOME directory to change to root’s home directory.

If you’ve already navigated to the directory you want to work in, the you shouldn’t use sudo -i as it will change the current directory. If it’s the first command you run after opening a shell, the it probably doesn’t really matter.

So in most cases I do use sudo -s (it’s 2 characters shorter than sudo bash ;-)) and in some rare cases sudo su. I personally never use sudo -i (anyway keeping sudo -s and sudo su in mind is already a lot for my small brain and remembering a third option will cause some overflow…).

And remember the additional password check which gets on your nerve when prefixing your commands with sudo once in a while might save you some day (especially if you start cleaning up files early in the morning before even having your first coffee of the day). So only switch to the root user if you really have to. Otherwise execute all commands you can with another user and only the ones which need root privileges with the root user.

SVN: Subversion 1.8 on Debian 7 (Wheezy)

Debian 7 (Wheezy) is still only shipping with Subversion 1.6 (see Details of package subversion in wheezy).

First you need to add the WANdisco GPG key to the apt sources keyring:

$ wget -q http://opensource.wandisco.com/wandisco-debian.gpg -O- | apt-key add -

Then you need to add the appropriate apt source. You can either extend /etc/apt/sources.list or create a new file in /etc/apt/sources.list.d. We’ll go for the second option:

$ echo "deb http://staging.opensource.wandisco.com/debian wheezy svn18" > /etc/apt/sources.list.d/subversion.list

Now you can have apt-get download the package lists from the new repository and update the dependencies:

$ apt-get update

Now apt-cache will show you (at least) two versions:

$ apt-cache show subversion
Package: subversion
Version: 1.8.8-3+WANdisco
Architecture: amd64
Maintainer: Philip Herron <opensource@wandisco.com>
Installed-Size: 4423
Depends: libsvn1 (= 1.8.8-3+WANdisco), libapr1 (>= 1.3.2), libaprutil1 (>= 1.2.7+dfsg), libc6 (>= 2.3), libexpat1 (>= 2.0.1), libsasl2-2 (>= 2.1.24), zlib1g (>= 1:1.1.4)
Suggests: subversion-tools, db4.8-util, patch
Filename: dists/wheezy/svn18/binary-amd64/subversion_1.8.8-3+WANdisco_amd64.deb
Size: 1453080
MD5sum: 8b23345878430ab7c5d22aabd461bbd6
SHA1: bc8125dfcc3c7bee34b09eca6919d5e64a7513d4
SHA256: 861987aebdcd2fa9f03ba9f758572fb05f8b345341533c0d072b5ef573443999
Section: vcs
Priority: optional
Homepage: http://wandisco.com
Description: Advanced version control system

Package: subversion
Version: 1.6.17dfsg-4+deb7u4
Installed-Size: 4108
Maintainer: Peter Samuelson <peter@p12n.org>
Architecture: amd64
Depends: libsvn1 (= 1.6.17dfsg-4+deb7u4), libapr1 (>= 1.2.7), libc6 (>= 2.3), libsasl2-2 (>= 2.1.24)
Suggests: subversion-tools, db5.1-util, patch
Description: Advanced version control system
Homepage: http://subversion.apache.org/
Description-md5: 15da1bb51fb2e9ea5e25b3a489b864d9
Tag: devel::rcs, implemented-in::c++, implemented-in::python,
 interface::commandline, network::client, network::server,
 protocol::http, protocol::ssh, protocol::webdav, role::program,
 use::storing, use::synchronizing
Section: vcs
Priority: optional
Filename: pool/main/s/subversion/subversion_1.6.17dfsg-4+deb7u4_amd64.deb
Size: 1319636
MD5sum: 608ed74ad8856546afd0a38ad171d0a5
SHA1: 46b53dc63ae20c59c39e152d65d68397c951051f
SHA256: a4a7fd1aefc7f160aa4a270792e5b7812a3804623d36b34f41055ed7a4b083a0

You can now install the new version using:

$ apt-get install subversion

Now Subversion 1.8 will be installed, you can check it with:

$ svn --version
svn, Version 1.8.8 (r1568071)
...

If you have already done all this for Subversion 1.7 and only want to upgrade to versino 1.8, it’s even easier. You just have to find where the source is defined (you don’t need to import the key as you already have it):

$ grep -R svn17 /etc/apt/
/etc/apt/sources.list.d/WANdisco.list:deb http://staging.opensource.wandisco.com/debian wheezy svn17

Then replace svn17 by svn18 in this file:

$ sed -i 's/svn17/svn18/' /etc/apt/sources.list.d/WANdisco.list

Now you can have apt-get download the package lists from the new repository and upgrade subversion:

$ apt-get update && apt-get upgrade

Horde webmail showing the default Plesk page

After migrating all our domains to a new server, whenever you wanted to access emails using the Horde webmail UI, you’d see the default Plesk page instead of the Horde login page.

Executing the following didn’t help (so Horde was already properly installed):

# /opt/psa/admin/bin/webmailmng --install --name=horde
# /opt/psa/admin/bin/webmailmng --enable --name=horde
# /opt/psa/admin/sbin/httpdmng --reconfigure-all

Webmail was turned on for these domains. After some time I also noticed that horde.webmail.mydomain.com was showing the login page instead of webmail.mydomain.com. So it seemed to be more of an Apache configuration issue than a problem with the Plesk installation itself.

First I looked for the httpd.conf file for Plesk:

# l /etc/apache2/conf.d/*psa*
-rw-r----- 1 root www-data 402 Jan  2 23:20 /etc/apache2/conf.d/zz010_psa_httpd.conf

Then looked for the corresponding horde file:

# grep horde /etc/apache2/conf.d/zz010_psa_httpd.conf 
Include '/etc/apache2/plesk.conf.d/horde.conf'

In this file, you’ll see the following:

# grep webmail /etc/apache2/plesk.conf.d/horde.conf
    ServerName horde.webmail
    ServerAlias horde.webmail.*
    Include "/etc/apache2/plesk.conf.d/webmails/horde/*.conf"
        FcgidInitialEnv PP_CUSTOM_PHP_INI "/etc/psa-webmail/horde/horde/php.ini"

Ok, so I’ve now found out the reason why horde.webmail is used instead of webmail. While looking for a solution, I’ve also seen that the very first domain I had migrated (ams-traduction.com) didn’t have this problem. So there was something different about this domain.

Looking at the files in /etc/apache2/plesk.conf.d/webmails/horde/ I saw that it was the only domain for which there was a file in there (ams-traduction.com_webmail.conf).

This file contained the following:

#ATTENTION!
#
#DO NOT MODIFY THIS FILE BECAUSE IT WAS GENERATED AUTOMATICALLY,
#SO ALL YOUR CHANGES WILL BE LOST THE NEXT TIME THE FILE IS GENERATED.

ServerAlias “webmail.ams-traduction.com”

So that’s why I could use the webmail URL instead of the horde.webmail URL for this domain. But why didn’t I have files for the other domains ? Since it you basically only needed the last line in the file, I added files for all domains. After that it worked… Until the next Plesk update. During the Plesk update all files in there except the first one (which I hadn’t added) got deleted and I had again the same problem.

Of course one solution is to replace horde.webmail by webmail in /etc/apache2/plesk.conf.d/horde.conf. But I wasn’t sure whether this wouldn’t also get deleted.

After a long search I finally figured out what was the difference between this one domain and the others. They belonged to different Plesk subscriptions. Looking at the subscription settings in Plesk I saw that there was also a Webmail configuration. After selecting Horde there, all the files were created automatically and the problem was solved.

This doesn’t really make sense to me. Why would you be able to enable Horde both for a subscription or for a domain but have a different behavior… Well, everything is not always logical in Plesk… Now let’s see whether the next update will again break it !

Sybase ASE: check contents of the procedure cache

In order to peek into the procedure cache, you can use the following dbcc command:

dbcc procbuf

In order to see the output on the console, use:

dbcc traceon(3604)
go
dbcc procbuf
go

You’ll see that the output is pretty extensive. If what you are after is which trigger and procedures are using space in the procedure cache and how much space it uses, you only are interested in the lines like:

...
    Total # of bytes used               : 1266320
...
pbname='sp_aux_getsize'   pbprocnum=1
...

You can thus execute it and grep for these two lines:

$SYBASE/OCS/bin/isql -Usa -Pxxxx << EOT | grep "pbname
Total # of bytes used"
dbcc traceon(3604)
go
dbcc procbuf
go
EOT

You of course need to replace xxxx by your actual password.

Then you will want to make it looks nicer:

  • Merge the two lines: awk ‘!(NR%2){print p” “$0}{p=$0}’
  • Display only the name and the size: awk ‘{ print $1″ “$9″ bytes”; }’ | sed “s/pbname=//g” | sed “s/’//g”
  • Sort by size: sed “s/’//g” | sort -k2 -n

Putting it all together:

$SYBASE/OCS/bin/isql -Usa -Pxxxx << EOT | grep "pbname
Total # of bytes used" | awk '!(NR%2){print p" "$0}{p=$0}' | awk '{ print $1" "$9" bytes"; }' | sed "s/pbname=//g" | sed "s/'//g" | sort -k2 -n 
dbcc traceon(3604)
go
dbcc procbuf
go
EOT

You will then see something like:

...
sp_jdbc_tables 62880 bytes
sp_getmessage 68668 bytes
sp_aux_getsize 80596 bytes
sp_mda 81433 bytes
sp_mda 81433 bytes
sp_drv_column_default 90144 bytes
sp_dbcc_run_deletehistory 133993 bytes
sp_lock 180467 bytes
sp_helpsegment 181499 bytes
sp_dbcc_run_summaryreport 207470 bytes
sp_modifystats 315854 bytes
sp_autoformat 339825 bytes
sp_spaceused 353572 bytes
sp_jdbc_columns 380403 bytes
sp_do_poolconfig 491584 bytes
sp_configure 823283 bytes

Linux: Working with jobs

I’ve noticed that many people I work with and have to do something in a Linux shell tend to not use jobs much. I’m not too sure whether it’s because they do not know how to use them or because it isn’t something they think about automatically. I actually use them very much. It might be because I’m getting old and keep forgetting to write an ampersand at the end of the line or because I don’t like have 10 terminal windows open…

Jobs are basically just commands you’ve started and run in the background or in the foreground. Foreground and background jobs are pretty similar, the difference is that for a foreground job, what you type in the terminal is directed to the standard input of the job (stdin) and for a background job it is goes to the shell process instead.

I guess everybody has already used jobs by starting something in the background using the ampersand e.g.:

# find / -name myfilename > /tmp/search.results

Would execute in the foreground i.e. block the terminal until it finishes and the following would run it as a background job:

# find / -name myfilename > /tmp/search.results &
[4] 17974

[4] means it’s the job number 4. This will be useful to know in order to bring it back to the foreground and send it again in the background.

If it finishes while still in the background, it will write the following to the console:

[4]   Exit 1                  find / -name myfilename > /tmp/search.results

Now, if you forgot the ampersand and started it in the foreground, you can suspend it by pressing Ctrl-Z:

# find / -name myfilename > /tmp/search.results
^Z
[1]+  Stopped                 find / -name myfilename > /tmp/search.results

The job is now stopped i.e. suspended and waiting to be resumed in the background or in the foreground. The plus after the job number means that it is the current process.

If you now call the command fg, it will bring it back to the foreground (it brings the current job back to the foreground):

# fg
find / -name myfilename > /tmp/search.results

And if you call the command bg instead, it will bring it back to the background:

# bg
[1]+ find / -name myfilename > /tmp/search.results

So if you started some long running job in the foreground and need to do something else in your shell but do not want to or cannot open another terminal window, just press CTRL-Z to suspend it, use bg to resume it in the background, do whatever you need to and then use fg to bring it back to the foreground.

Now if you do not want to resume the current job to the background or the foreground but another job you’ve suspended earlier, you can use the job number to resume a specific job:

# bg %2
[2]- find / -name 2myfilename > /tmp/search.results &
# bg %3
[3]+ find / -name 2myfilename > /tmp/search.results &
# fg %1
find / -name 2myfilename > /tmp/search.results

You can see all jobs using the jobs command:

# jobs
[1]   Stopped                 find / -name *myfilename* > /tmp/search.results
[2]-  Stopped                 find / -name *myfilename2* > /tmp/search.results
[3]+  Stopped                 find / -name *myfilename3* > /tmp/search.results

If you have some background jobs, it will look like this:

# jobs
[2]-  Stopped                 find / -name *myfilename2* > /tmp/search.results
[3]+  Stopped                 find / -name *myfilename3* > /tmp/search.results
[4]   Running                 find / -name *myfilename4* > /tmp/search.results &

You can also use the kill command to kill these jobs:

# kill %3
[3]   Terminated              find / -name *myfilename3* > /tmp/search.results

Of course, you all know that you can kill the current job by pressing CTRL-C.