Header RSS Feed
 
If you only want to see the articles of a certain category, please click on the desired category below:
ALL Android Backup BSD Database Hacks Hardware Internet Linux Mail MySQL Nagios/Monitoring Network Personal PHP Proxy Shell Solaris Unix Virtualization VMware Windows Wyse

Limit http request methods in Nginx (authentication except for GET)
Tuesday - May 31st 2016 - by - (0 comments)

Was looking for a way to tell Nginx to let all GET requests through but all other requests (e.g. POST, PUT, etc) should be authenticated.

On my research I found a lot of examples using "if", like this one (found on https://www.acunetix.com/blog/articles/nginx-server-security-hardening-configuration-1/):

if ($request_method !~ ^(GET|HEAD|POST)$ )
{
    return 444;
}

However there are two problems.

1) if is evil: https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/ 

2) basic auth does not work within an if clause in Nginx. So the following snippet doesn't work:

if ($request_method !~ ^GET$ )
{
  auth_basic "Login required";
  auth_basic_user_file /etc/nginx/auth/.htpasswd;
}

Belive me, I tried it and fell on my nose... On my research WHY it fails, I came across this page: https://t37.net/the-good-the-bad-and-the-ugly-of-virtual-hosting-with-nginx.html, which explains it nicely:

The reason why it fails is because if is not part of the general configuration module as one should believe. if is part of the rewrite module and auth_basic is another module. Thats one of the reason why the Nginx community thinks if is evil.

Eventually I came across the limit_except method, which is part of the Nginx core module. By using this method, one can define special limits for http request methods. The documentation (http://nginx.org/en/docs/http/ngx_http_core_module.html#limit_except) describes the method in a bizarre way though:

Limits allowed HTTP methods inside a location. The method parameter can be one of the following: GET, HEAD, POST, PUT, DELETE, MKCOL, COPY, MOVE, OPTIONS, PROPFIND, PROPPATCH, LOCK, UNLOCK, or PATCH. Allowing the GET method makes the HEAD method also allowed. Access to other methods can be limited using the ngx_http_access_module and ngx_http_auth_basic_module modules directives

What I mean with bizarre: It's not clear whether the limitation is now for the mentioned request methods or for the unlisted request methods. But a configuration change quickly showed me that it works the following way:

  location /api/ {

    # Only allow GET, all other methods require basic auth
    limit_except GET {
      auth_basic           "Login required";
      auth_basic_user_file /etc/nginx/auth/.htpasswd;
    }

    include /etc/nginx/proxy.conf;
    proxy_pass       http://127.0.0.1:8080;
  }

The comment I added just above limit_except explains it: Set a limit for all http request methods (load the auth_basic stuff) EXCEPT the request method is GET.

Works nicely and I didn't have to use "if" either.

 

New version of check_esxi_hardware allows different CIM ports (NAT)
Tuesday - May 31st 2016 - by - (0 comments)

There's a new version (20160531) of the Monitoring Plugin to monitor the hardware of ESXi servers, check_esxi_hardware.py, out! This version contains a new feature which allows manually define the CIM port.

The default CIM port listens on tcp/5989. However if you have several ESXi servers behind one IP address (NAT) you can now use port forwardings on your firewall our router and monitor all of them, too.

The newly added parameter is "-C" (--cimport). Documentation of check_esxi_hardware is up to date, too.

Enjoy!

 

Shopware shows content correctly but with http status 503
Monday - May 30th 2016 - by - (0 comments)

Had a strange case of application problem today, when a webshop running on Shopware 5.x started to sporadically return http 503 status and therefore triggering our monitoring system and disabling the website in the reverse proxies (which are running in front of the application server). 

By fiddling around with local hosts entries and therefore bypassing the reverse proxies, something strange could be seen in the browser: The web shop is shown correctly, however the HTTP status from the application server is a 503 (see screenshot).

Shopware content error 503 

First it started off with sporadic 503 returns but after a while every request got a 503 status return. Neither in the Apache/PHP nor in the Shopware logs was a hint what would cause this. More or less by chance I decided to rename the cache folder (SHOPWARE_ROOT/var/cache) and create a new empty cache folder. And voil, the application worked again and displayed the shop once again with a correct HTTP 200 status code.

 

SpamAssassin stopped working? Check loopback interface!
Thursday - May 26th 2016 - by - (0 comments)

Got the following error messages on a mailserver:

spamc[11629]: connect to spamd on 127.0.0.1 failed, retrying (#2 of 3): Connection timed out

A manual restart of spamassassin only resulted in the following error:

/etc/init.d/spamassassin restart
Restarting SpamAssassin Mail Filter Daemon: No /usr/bin/perl found running; none killed.
[12244] warn: server socket setup failed, retry 1: spamd: could not create INET socket on 127.0.0.1:783: Cannot assign requested address
[12244] warn: server socket setup failed, retry 2: spamd: could not create INET socket on 127.0.0.1:783: Cannot assign requested address
[12244] warn: server socket setup failed, retry 3: spamd: could not create INET socket on 127.0.0.1:783: Cannot assign requested address
[12244] warn: server socket setup failed, retry 4: spamd: could not create INET socket on 127.0.0.1:783: Cannot assign requested address
[12244] warn: server socket setup failed, retry 5: spamd: could not create INET socket on 127.0.0.1:783: Cannot assign requested address
[12244] warn: server socket setup failed, retry 6: spamd: could not create INET socket on 127.0.0.1:783: Cannot assign requested address
[12244] warn: server socket setup failed, retry 7: spamd: could not create INET socket on 127.0.0.1:783: Cannot assign requested address
[12244] warn: server socket setup failed, retry 8: spamd: could not create INET socket on 127.0.0.1:783: Cannot assign requested address
[12244] warn: server socket setup failed, retry 9: spamd: could not create INET socket on 127.0.0.1:783: Cannot assign requested address
[12244] error: spamd: could not create INET socket on 127.0.0.1:783: Cannot assign requested address
spamd: could not create INET socket on 127.0.0.1:783: Cannot assign requested address

First I suspected a hanging PID file somewhere or an already opened listener port 783 (but then usually an error "address already in use" is shown). But nope, port was free to be used.

Only when I checked ip addr show all became clear:

ip addr show
1: lo: mtu 16436 qdisc noop state DOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 8c:89:a5:15:6b:9d brd ff:ff:ff:ff:ff:ff
    inet 123.4.5.123/32 brd 123.4.5.255 scope global eth0
[...]

The loopback (lo) interface was DOWN! This happened because this server had a network problem after the boot and the activation of the loopback interface got forgotten (yet eth0 was working as it should).
After enabling the lo interface and restart SpamAssassin, all worked again:

ifup lo

/etc/init.d/spamassassin restart
Restarting SpamAssassin Mail Filter Daemon: No /usr/bin/perl found running; none killed.
spamd.

 

How to retrieve values from json output in bash
Friday - Apr 29th 2016 - by - (0 comments)

Sure, one could get a json output with curl and then do all kinds of grepping, sedding and awking. But there is actually a cool way, to get the value directly by accessing the json objects. The magic is done by jshon

Fortunately this (cli-)program doesn't need to be compiled manually, in Ubuntu it can be downloaded from the official repos:

sudo apt-get install jshon

Now let's do some json'ing. Let's take the ElasticSearch cluster stats for example. As you may know, you can get the current ES cluster statistics and information from the following URL: http://your.es.node:9200/_cluster/stats (for a human readable output you can use http://your.es.node:9200/_cluster/stats?human&pretty). 

The json output is separated into several objects. You can use jshon to list them:

$ curl "http://elasticsearch.local:9200/_cluster/stats" -s | jshon -k
timestamp
cluster_name
status
indices
nodes

As you see above, I directly accessed the ES URL and piped the output to jshon. The -k parameter returns a list of keys. In this case we got 5 keys.

The value I am looking for is within the "indices" key, so I first display the values of the full key with the -e parameter (returns json value):

$ curl "http://elasticsearch.local:9200/_cluster/stats" -s | jshon -e indices
{
 "count": 13,
 "shards": {
  "total": 61,
  "primaries": 61,
  "replication": 0.0,
  "index": {
   "shards": {
    "min": 1,
    "max": 5,
    "avg": 4.6923076923076925
   },
   "primaries": {
    "min": 1,
    "max": 5,
    "avg": 4.6923076923076925
   },
   "replication": {
    "min": 0.0,
    "max": 0.0,
    "avg": 0.0
   }
  }
 },
 "docs": {
  "count": 935249,
  "deleted": 196434
 },
 "store": {
  "size": "11.9gb",
  "size_in_bytes": 12860502682,
  "throttle_time": "3.7h",
  "throttle_time_in_millis": 13374212
 },
 "fielddata": {
  "memory_size": "7.9mb",
  "memory_size_in_bytes": 8328212,
  "evictions": 0
 },
 "filter_cache": {
  "memory_size": "78.1mb",
  "memory_size_in_bytes": 81991016,
  "evictions": 72989502
 },
 "id_cache": {
  "memory_size": "0b",
  "memory_size_in_bytes": 0
 },
 "completion": {
  "size": "0b",
  "size_in_bytes": 0
 },
 "segments": {
  "count": 453,
  "memory": "17.9mb",
  "memory_in_bytes": 18873642,
  "index_writer_memory": "0b",
  "index_writer_memory_in_bytes": 0,
  "index_writer_max_memory": "190.1mb",
  "index_writer_max_memory_in_bytes": 199421333,
  "version_map_memory": "0b",
  "version_map_memory_in_bytes": 0,
  "fixed_bit_set": "3.2mb",
  "fixed_bit_set_memory_in_bytes": 3448160
 },
 "percolate": {
  "total": 0,
  "get_time": "0s",
  "time_in_millis": 0,
  "current": 0,
  "memory_size_in_bytes": -1,
  "memory_size": "-1b",
  "queries": 0
 }
}

So this is the full output, but not the single value of what I actually wanted. To do this, the subkeys within the "indices" key can be shown and used the same way:

$ curl "http://elasticsearch.local:9200/_cluster/stats" -s | jshon -e indices -k
percolate
shards
count
store
docs
fielddata
filter_cache
id_cache
completion
segments

So now we got a nice list of the subkeys which we can access directly with an additional -e:

$ curl "http://elasticsearch.local:9200/_cluster/stats" -s | jshon -e indices -e store
{
 "size": "11.9gb",
 "size_in_bytes": 12860502682,
 "throttle_time": "3.7h",
 "throttle_time_in_millis": 13374212
}

And to get the final single value I wanted from the start, this can be retrieved by using yet another -e parameter:

$ curl "http://elasticsearch.local:9200/_cluster/stats" -s | jshon -e indices -e store -e "size_in_bytes"
12860502682

 

Amazon S3 bucket and Internet Explorer 11: HTTP 400 error because of umlaut
Friday - Apr 29th 2016 - by - (0 comments)

There was a strange phenomenon this week at work when trying to access a certain PDF element from an AWS S3 bucket containing a German umlaut () in the filename.

While on Chrome (50) and Firefox (45) it worked correctly (an XML answer showed correctly up, as it was expected in this case), it never worked on Internet Explorer (11).

After using the debug/developer tools (F12 in IE) I saw the following response which wasn't displayed in the browser itself:


InvalidArgumentHeader value cannot be represented using ISO-8859-1.response-content-dispositionattachment; filename=Eat_My_Zn?ni.pdf3E7CFF47D4A6BF23IfEECJc5hXFcmZXshxPKKJg/GCw+1gaWiyc+wXvvlmNTCJ7t3A8YrKARXI0tLnK0QkvAKnuNJBE=

So Internet Explorer 11 seems to have problems to encode the umlaut from ISO-88591- into UTF-8 (although this setting is activated in the Internet Options -> Advanced -> International). 

When writing ue instead of it worked.

Update May 3rd 2016:
My colleague just found out that this only happens in a recent version of IE11. On Internet Explorer 11 Version 11.0.9600.16521 it was working. Another non-working version is 11.0.9600.17278 and the IE version I tested with was 11.0.9600.18282.

 

Did you know Skype understands sed? Replace previous line with sed command!
Wednesday - Apr 27th 2016 - by - (0 comments)

Just found out something funny: Skype understands sed! I was pretty surprised when my sed command worked in Skype and changed a word in my previous written line.

Check this out:

Skype replace with sed

Skype replace with sed

Skype replace with sed

Tested on Skype 4.3.0.37 on Linux Mint 17.3. That just made my day ^_^.

 

Avoid Ansible writing several times the same line in /etc/sudoers
Monday - Apr 25th 2016 - by - (0 comments)

When I ran an Ansible playbook which added an entry in /etc/sudoers for a user "developer" I came across something rather ugly: The line was written every time the playbook ran - resulting in an /etc/sudoers full of the same entries of the developer user.

The relevant task of the playbook looked like this:

  - name: DEVS - Add sudoers entry for developer
    lineinfile: "dest=/etc/sudoers
                regexp='^developer ALL=(www-data)'
                insertafter='^# User privilege specification'
                line='developer ALL=(www-data) NOPASSWD: /bin/bash'
                state=present"

So what I want to achieve with this is the following:

In /etc/sudoers search for a line starting with "developer ALL=(www-data)".
If this line is not found, write the line "developer ALL=(www-data) NOPASSWD: /bin/bash" into /etc/sudoers, right after the line starting with "# User privilege specification".

To my big surprise, whenever I ran the playbook, it executed the task and set it to "changed". Meaning, the entry was added. So at the end /etc/sudoers contained several lines of "developer ALL=(www-data) NOPASSWD: /bin/bash". That's not what I wanted to achieve.

After some troubleshooting it turned out that the regular expression "developer ALL=(www-data)" didn't work because of the brackets ( ). As ansible is using python in the background, I checked out the python regular expression documentation and searched for an escape character. No big surprise here, the escape character is a backslash (\) as it is in Perl's regular expression, too.

I adapted the playbook to escape the brackets:

  - name: DEVS - Add sudoers entry for developer
    lineinfile: "dest=/etc/sudoers
                regexp='^developer ALL=\(www-data\)'
                insertafter='^# User privilege specification'
                line='developer ALL=(www-data) NOPASSWD: /bin/bash'
                state=present"

But now I ran into a YAML syntax error:

ERROR! Syntax Error while loading YAML.

The error appears to have been in 'myplaybook.yaml': line 57, column 36, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

    lineinfile: "dest=/etc/sudoers
                regexp='^developer ALL=\(www-data\)'
                                   ^ here

So the escape character didn't work because YAML didn't like it. Finally I came across the answer: Wrap the character I want to escape in a separate character class and this is how it's done:

  - name: DEVS - Add sudoers entry for developer
    lineinfile: "dest=/etc/sudoers
                regexp='^developer ALL=[(]www-data[)]'
                insertafter='^# User privilege specification'
                line='developer ALL=(www-data) NOPASSWD: /bin/bash'
                state=present"

The playbook now runs through and the sudoers entry only exists once.

 

Disable autostart of lxcbr0 on Ubuntu 16.04 xenial
Friday - Apr 22nd 2016 - by - (1 comments)

One of the major changes on Ubuntu 16.04 (Xenial) is the integration of LXD using LXC 2.0 in the background.
Although I love LXC, I'm kind of annoyed by the fact, that it comes as part of the "base" installation. If I want LXD/LXC, I install it manually. 

Because LXD is now installed by default, the LXC bridge (lxcbr0) is now started automatically:

root@xenial:~# ifconfig
ens160    Link encap:Ethernet  HWaddr 00:50:56:99:37:c4 
          inet addr:10.10.10.10  Bcast:10.10.10.255  Mask:255.255.255.0
          inet6 addr: fe80::250:56ff:fe99:37c4/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:918 errors:0 dropped:1 overruns:0 frame:0
          TX packets:441 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:78692 (78.6 KB)  TX bytes:92428 (92.4 KB)

lo        Link encap:Local Loopback 
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

lxcbr0    Link encap:Ethernet  HWaddr 86:dc:ff:84:80:20 
          inet addr:10.0.3.1  Bcast:0.0.0.0  Mask:255.255.255.0
          inet6 addr: fe80::84dc:ffff:fe84:8020/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:570 (570.0 B)

To disable the automatic start of the virtual bridge lxcbr0, adapt /etc/default/lxc-net and set USE_LXC_BRIDGE to false:

root@xenial:~# sed -i "/USE_LXC_BRIDGE/s/true/false/g" /etc/default/lxc-net

This disables the automatic start of the virtual bridge at boot time.

To turn off and delete the bridge during runtime:

root@xenial:~# ifconfig lxcbr0 down
root@xenial:~# brctl delbr lxcbr0

 

check_disk on Ubuntu 16.04 xenial reports DISK CRITICAL: / not found
Friday - Apr 22nd 2016 - by - (0 comments)

Recently I wrote about how an Ubuntu xenial container can be created on an Ubuntu trusty host. As I've started to create new xenial containers like this in the last days and added them into Icinga 2 monitoring, I was pretty surprised when check_disk wasn't working.

Instead of showing the usage of a given partition (with the -p parameter), it reported that the partition could not be found:

root@xenial:~# /usr/lib/nagios/plugins/check_disk -w 10% -c 5% -p /
DISK CRITICAL: / not found

First I suspected a problem from check_disk itself, because Xenial now uses the package monitoring-plugins instead of nagios-plugins:

root@xenial:~# apt-cache search nagios-plugins
nagios-plugins - transitional dummy package (nagios-plugins to monitoring-plugins)
[...]

As I mentioned above, this xenial container runs on a trusty host. I copied the check_disk plugin from within the container onto the trusty host and ran it:

root@trusty:/tmp# ./check_disk -w 10% -c 5% -p /
DISK OK - free space: / 2412 MB (55% inode=57%);| /=1897MB;4107;4335;0;4564

So it's working. Where's the difference? With strace I was able to find out the following:

root@xenial:~# strace /usr/lib/nagios/plugins/check_disk -w 10% -c 5% -p
execve("./check_disk_trusty", ["./check_disk_trusty", "-w", "10%", "-c", "5%", "-p", "/"], [/* 36 vars */]) = 0
brk(NULL)                               = 0x7f4e00293000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4dff4df000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=18670, ...}) = 0
mmap(NULL, 18670, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f4dff4da000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\360`\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=138744, ...}) = 0
mmap(NULL, 2212904, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f4dfee8f000
mprotect(0x7f4dfeea7000, 2093056, PROT_NONE) = 0
mmap(0x7f4dff0a6000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x17000) = 0x7f4dff0a6000
mmap(0x7f4dff0a8000, 13352, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f4dff0a8000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\t\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1864888, ...}) = 0
mmap(NULL, 3967488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f4dfeac6000
mprotect(0x7f4dfec86000, 2093056, PROT_NONE) = 0
mmap(0x7f4dfee85000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1bf000) = 0x7f4dfee85000
mmap(0x7f4dfee8b000, 14848, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f4dfee8b000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4dff4d9000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4dff4d8000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4dff4d7000
arch_prctl(ARCH_SET_FS, 0x7f4dff4d8700) = 0
mprotect(0x7f4dfee85000, 16384, PROT_READ) = 0
mprotect(0x7f4dff0a6000, 4096, PROT_READ) = 0
mprotect(0x7f4dff4e1000, 4096, PROT_READ) = 0
mprotect(0x7f4dff2d1000, 4096, PROT_READ) = 0
munmap(0x7f4dff4da000, 18670)           = 0
set_tid_address(0x7f4dff4d89d0)         = 17605
set_robust_list(0x7f4dff4d89e0, 24)     = 0
rt_sigaction(SIGRTMIN, {0x7f4dfee94b90, [], SA_RESTORER|SA_SIGINFO, 0x7f4dfeea03d0}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {0x7f4dfee94c20, [], SA_RESTORER|SA_RESTART|SA_SIGINFO, 0x7f4dfeea03d0}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
getrlimit(RLIMIT_STACK, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
brk(NULL)                               = 0x7f4e00293000
brk(0x7f4e002b4000)                     = 0x7f4e002b4000
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2981280, ...}) = 0
mmap(NULL, 2981280, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f4dfe7ee000
close(3)                                = 0
open("/etc/mtab", O_RDONLY|O_CLOEXEC)   = 3
futex(0x7f4dfee8c068, FUTEX_WAKE_PRIVATE, 2147483647) = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
read(3, "", 4096)                       = 0
close(3)                                = 0
stat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("/etc/mtab", O_RDONLY|O_CLOEXEC)   = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
read(3, "", 4096)                       = 0
close(3)                                = 0
open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2995, ...}) = 0
read(3, "# Locale name alias data base.\n#"..., 4096) = 2995
read(3, "", 4096)                       = 0
close(3)                                = 0
open("/usr/share/locale/en_US/LC_MESSAGES/nagios-plugins.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/nagios-plugins.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/en_US/LC_MESSAGES/nagios-plugins.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/en/LC_MESSAGES/nagios-plugins.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 17), ...}) = 0
write(1, "DISK CRITICAL: / not found\n", 27DISK CRITICAL: / not found
) = 27
exit_group(2)                           = ?
+++ exited with 2 +++

The relevant part is this one:

open("/etc/mtab", O_RDONLY|O_CLOEXEC)   = 3
futex(0x7f4dfee8c068, FUTEX_WAKE_PRIVATE, 2147483647) = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
read(3, "", 4096)                       = 0
close(3)                                = 0
stat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("/etc/mtab", O_RDONLY|O_CLOEXEC)   = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
read(3, "", 4096)                       = 0
close(3)                                = 0

The file /etc/mtab is used by check_disk to get the values. However this file is empty in the xenial container:

root@xenial:~# ls -la /etc/mtab
-rw-r--r-- 1 root root 0 Apr 22 07:09 /etc/mtab

root@xenial:~# cat /etc/mtab
root@xenial:~#

A solution to this if /etc/mtab is symlinked to /proc/mounts which should contain the same information:

root@xenial:~# test -f /etc/mtab && rm /etc/mtab; ln -s /proc/mounts /etc/mtab
rm: remove regular empty file '/etc/mtab'? y

root@xenial:~# cat /etc/mtab
rootfs / rootfs rw 0 0
/dev/vglxc/xenial / ext4 rw,relatime,data=ordered 0 0
proc /proc proc rw,nosuid,nodev,noexec,relatime 0 0
sysfs /sys sysfs rw,relatime 0 0
none /sys/fs/fuse/connections fusectl rw,relatime 0 0
none /sys/kernel/debug debugfs rw,relatime 0 0
none /sys/kernel/security securityfs rw,relatime 0 0
none /sys/fs/pstore pstore rw,relatime 0 0
devpts /dev/lxc/console devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0
devpts /dev/lxc/tty1 devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0
devpts /dev/lxc/tty2 devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0
devpts /dev/lxc/tty3 devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0
devpts /dev/lxc/tty4 devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000 0 0
devpts /dev/pts devpts rw,relatime,gid=5,mode=620,ptmxmode=666 0 0
devpts /dev/ptmx devpts rw,relatime,gid=5,mode=620,ptmxmode=666 0 0
none /sys/fs/cgroup tmpfs rw,relatime,size=4k,mode=755 0 0
none /run tmpfs rw,nosuid,noexec,relatime,size=611212k,mode=755 0 0
none /run/lock tmpfs rw,nosuid,nodev,noexec,relatime,size=5120k 0 0
none /run/shm tmpfs rw,nosuid,nodev,relatime 0 0
none /run/user tmpfs rw,nosuid,nodev,noexec,relatime,size=102400k,mode=755 0 0

And now the check_disk plugin works again:

root@xenial:~# /usr/lib/nagios/plugins/check_disk -w 10% -c 5% -p /
DISK OK - free space: / 1060 MB (57% inode=77%);| /=773MB;1755;1853;0;1951

 


Go to Homepage home
Linux Howtos how to's
Nagios Plugins nagios plugins
Links links

Valid HTML 4.01 Transitional
Valid CSS!
[Valid RSS]

7902 Days
until Death of Computers
Why?