Tag Archives: proxy

SNMP hell (part 1): proxy to multiple devices

Last week I started working on the @GEMwrld HPC cluster at the Eidgenössische Technische Hochschule Zürich (ETH). The first task was to implement a kind of system monitoring and resource profiling. We already have a centralized graphical web console, built upon Observium, that collect resources statistics from all of our servers; usually we use SNMP v2c and, just for a few cases, the munin-node daemon (more on this will be in the part 2).

On the ETH cluster we have full access to every node, but the only incoming connections allowed by the ETH firewall are the SSH sessions (on port 22), so there’s a first problem: how can we transport SNMP data from the agent to the poller?

The answer is easy: SSH tunnel! But: usually SNMP uses UDP protocol; making an UDP SSH tunnel is a bit painful. To workaround this issue we had simply used the TCP protocol for SNMP.

First of all you need an SSH tunnel. In this case the tunnel is made by the monitoring server:

ssh -N monitoring@serverip -L 16000:localhost:161

The 161 is the remote TCP port to be forwarded and 16000 is the local port.

To use SNMP on TCP you have to modify the net-snmp daemon (snmpd) command line parameters (and not the snmpd config file); just edit /etc/default/snmpd (on ubuntu/debian, for RHEL the path is /etc/sysconfig/snmpd) as following:

SNMPDOPTS='-LF 6 /var/log/snmpd.log -u snmp -g snmp -I -smux -p /var/run/snmpd.pid TCP:161'

The important part is ‘TCP:161’. This will bind snmpd on every interface and on the TCP port 161 (the default SNMP port).
On the poller side you will need to configure your monitoring system to poll localhost:16000 with tcp protocol. For Observium you can add the host with:

./addhost.php localhost  community v2c 16000 tcp

Now there’s another problem. The Zurich GEM cluster is made by eight nodes and I do not want to start an SSH tunnel on every node. Then my idea was to use a kind of proxy on the control node:

eth_snmp

net-snmp helped me with the snmpd proxy capabilities: http://www.net-snmp.org/wiki/index.php/Snmpd_proxy

Continue reading

WordPress caching with nginx

As a part of my friend @zenkay post on his blog here it is a simple but efficient nginx configuration for proxying and caching an Apache + WordPress installation.

Assuming that:

  • nginx and Apache are on different nodes: if nginx and Apache are on the same machine is highly advised to serve static files directly from nginx;
  • static files expire header is managed by Apache (through mod_expires); if static stuff is served directly you need to specify the expire through nginx;
  • you have installed the WordPress Nginx proxy cache integrator;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
server {
    # Listen IPv6 and IPv4 socket
    listen       [::]:80; #on Linux this means both IPv4 and IPv6
    # Name-based virtualhosts
    server_name  *.mydomain.com mydomain.com;
 
    # Add Cache-Status debug header on replies
    add_header X-Cache-Status $upstream_cache_status;
 
    # Set the vhost access-log
    access_log  /var/log/nginx/access-mydomain.log  main;
 
    location / {
 
        # Skip^1 caching variable init
        set $nocache 0;
        # Bypass^2 caching variable init
        set $purgecache 0;
 
        # Bypass^2 cache on no-cache (et al.) browser request
        if ($http_cache_control ~ "max-age=0")
            { set $purgecache 1; }
        if ($http_cache_control ~ "no-cache")
            { set $purgecache 1; }
        # Bypass^2 cache with custom header set on request
        if ($http_x_cache_purge ~* "true")
            { set $purgecache 1; }
        # Skip^1 caching when WordPress cookies are set
        if ($http_cookie ~* "comment_author_|wordpress_(?!test_cookie)|wp-postpass_" )
            { set $nocache 1; }
 
        # Cache pool
        proxy_cache             proxy-one;
        # Bypass^2 cache when $purgecache is set to 1.
        # Bypass means that content is served fresh and the cache is updated
        proxy_cache_bypass      $purgecache;
        # Skip^1 caching when $nocache is set to 1
        # Do not cache when browsing frontend as logged user
        proxy_no_cache          $nocache;
        # Define the cache resource identifier. Be careful to add $nocache
        proxy_cache_key         "$scheme$http_host$request_uri$args$nocache";
        proxy_connect_timeout   10;
        proxy_read_timeout      10;
        # use stale cache on backend fault
        proxy_cache_use_stale   error timeout invalid_header updating http_500 http_502 http_503 http_504;
        proxy_cache_valid       200 302 15m;
        proxy_cache_valid       404 1m;
        proxy_set_header        Host             $host;
        proxy_set_header        X-Real-IP        $remote_addr;
        proxy_set_header        X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_pass              http://apache_remote_ip;
    }
 
    location ~* \/blog\/wp\-.*\.php|\/blog\/wp\-admin {
        proxy_cache             off;
        proxy_pass              http://apache_remote_ip;
    }
 
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
 
}

1^ see: http://wiki.nginx.org/HttpProxyModule#proxy_no_cache
2^ see: http://wiki.nginx.org/HttpProxyModule#proxy_cache_bypass

SSH SOCKS forwarding

A volte può capitare la necessità di effettuare tunneling verso un altra rete, vuoi per la necessità di accedere alla rete stessa, vuoi per poter fare da ponte e utilizzare un altro gateway verso il web.

Il primo caso può essere utile ad esempio per accedere a un host in una rete locale non raggiungibile attraverso il NAT, che è quello che a me spesso capita.

Le soluzioni più eleganti e raffinate prevedono l’utilizzo di VPN, ma c’è una soluzione ancora più semplice. Avendo una macchina all’interno della rete a cui ci si vuole collegare ed avendo installato SSH raggiungibile dall’esterno è possibile utilizzare il tunneling (criptato) tramite il forwarding SOCKS5 con un semplice comando:

ssh -C2qTnN -D 8080 username@remotehost

Questo comando va eseguito sulla macchina locale (deve anche qui essere installato SSH). Per Windows è possibile utilizzare putty. Esso creerà una connessione SSH verso remotehost senza shell e rimarrà in ascolto sulla porta locale 8080. Si presume che la porta remota sia la 22, se così non fosse è possibile specificare con il flag -p la porta di SSH sull’host remoto.

E’ possibile attivare il farwarding e una shell remota contemporaneamente; per farlo vanno tolti i flag -T -n e -N.

Ora che il tunnel è creato è possibile attivare l’accesso ad esso: per i browser è sufficiente andare nella configurazione proxy ed attivare il proxy attraverso SOCKS5: i parametri saranno localhost come host e 8080 la porta (o quella definita dal parametro -D). Inserendo un indirizzo della rete locale a cui si è connessi in tunnel sarà possibile accedere ad esso.

Per le applicazioni che non supportano SOCKS, o per cui non esiste una gui apposita di configurazione, esiste in Linux un comodissimo wrapper: tsocks.

Per prima cosa bisogna provvedere ad installarlo: su Fedora è sufficiente un

yum install tsocks

per poi creare il file di configurazione /etc/tsocks.conf così impostato

server = localhost
server_port = 8080
server_type = 5
local = 127.0.0.0/255.0.0.0

infine per l’utilizzo sarà sufficiente dare da shell il comando

tsocks applicazione

(è possibile anche creare una nuova shell con attivo di default il wrapper eseguendo il solo comando tsocks).
Per verificare se è attivo il wrapping delle connessioni il comando

export | grep tsocks

deve restituire

declare -x LD_PRELOAD="libtsocks.so"

Per terminare il forwarding sarà sufficiente chiudere il processo ssh (con ctrl-c nel caso non sia stato allocato un tty).

Riferimenti

  • man ssh
  • man tsocks