apt-get install arp-scan
arp-scan --interface=eth0 --localnet | grep b8:27:eb
172.16.12.34 b8:27:eb:00:11:ab (Unknown)
ssh -l pi 172.16.12.34
apt-get install arp-scan
arp-scan --interface=eth0 --localnet | grep b8:27:eb
172.16.12.34 b8:27:eb:00:11:ab (Unknown)
ssh -l pi 172.16.12.34
Today I figured out how to automatically add new devices (in my case those are mostly virtual machines) to the Zenoss monitoring system. This used to be done by hand, but no more 🙂
To add a new device (for example a Linux server called server001), simply call:
curl -u apiUser:apiPass \ 'http://zenoss-server:8080/zport/dmd/DeviceLoader? \ deviceName=server001&devicePath=/Server/Linux&\ loadDevice:method=1'
It’s wise to create a dedicated Zenoss user just for these API calls, but you may use any account that has sufficient permissions to perform the action you’re calling.
As an alternative you can also use the ‘zenbatchload‘ command. Although you can only add new devices, not edit existing ones.The RESTful API does have the possibility to edit an existing device.
Let’s set some properties to the server we’ve just added:
curl -u apiUser:apiPass \ 'http://zenoss-server:8080/zport/dmd/Devices/Server/\ Linux/devices/server001/manage_editDevice?serialNumber=1234&\ tag=tagname&productionState=1000&\ groupPaths=Group1&groupPaths=Group2&priority=3&\ comments=Api%20Test%20Comment&systemPaths=/System\ &rackSlot=Virtual'
It took me some time to figure out all available attributes, although once I found some of them I was able to Google the full list with an explaination.
Attributes:
Finally, in case you wish to delete a device, that can be done as well:
curl -u apiUser:apiPass \ 'http://zenoss-server:8080/zport/dmd/Devices/Server/Linux/\ devices/server001/deleteDevice'
Personally I prefer not to delete devices. I rather set the ‘productionState’ to ‘-1’ (Decommissioned) to keep the history in Zenoss.
These simple API calls make it possible to automatically add a new server to the monitoring, or sync information from another source. But you can use the API for gathering all sorts of data as well. For example the load-average:
curl -u apiUser:apiPass \ 'http://zenoss-server:8080/zport/dmd/Devices/Server/Linux/\ devices/server001/getRRDValue?dsname=laLoadInt5_laLoadInt5'
Result:
2.0
If you want to start playing with it, have a look at the Zenoss API documentation.
Recently I was looking for a way to SSH from a network that blocked my outgoing SSH connection. I’d be nice to have a way around firewalls and be able to access your private Linux terminal. To be able to debug a problem from an remote location, for example.
A collegue suggested a tool called ‘Shell In A Box‘. Shell In A Box implements a web server that can export arbitrary command line tools to a web based terminal emulator using just JavaScript and CSS without any additional browser plugins. This means: connecting your browser via HTTPS to your own hosted Shell In A Box web site, and access a Linux terminal from there.
How cool is that? In this blog I’ll show you how to set it up in a secure way.
Building and installing Shell In A Box
I want to setup Shell In A Box on my Raspberry Pi. It’s a great device running Linux that has a very small energy consumption footprint. Ideal for an always-on device I’d say!
Since there is no package available, we’ve to compile our own. It’s best to get the sources from Github (original here), since the Github repository contains some patches and fixes for issues on Firefox.
These commands install the required dependencies, clone the Git repository and start building:
apt-get install git dpkg-dev debhelper autotools-dev libssl-dev libpam0g-dev zlib1g-dev libssl1.0.0 libpam0g openssl git clone https://github.com/pythonanywhere/shellinabox_fork cd shellinabox_fork dpkg-buildpackage
During my first attempt, I ran into this problem:
dpkg-source -b shellinabox-2.14
dpkg-source: error: can't build with source format '3.0 (quilt)': no upstream tarball found at ../shellinabox_2.14.orig.tar.{bz2,gz,lzma,xz}
dpkg-buildpackage: error: dpkg-source -b shellinabox-2.14 gave error exit status 255
When grepping for ‘quilt’ I found a file called ‘/debian/source/format’. From what I can tell this does not do anything important, so I ended up deleting the file. Guess what, it now works.
rm ./debian/source/format
Build the package again, this should now succeed.
dpkg-buildpackage
This process will take some time (especially on the Raspberry Pi). Afterwards you’ll find the .deb file ready to be installed.
dpkg -i ../shellinabox_2.14-1_armhf.deb
I changed the configuration, to disallow the build-in SSL and to bind to localhost only. I did this because another web server will serve our terminal. I will explain in a minute.
vim /etc/default/shellinabox
And edit this line:
SHELLINABOX_ARGS="--no-beep -s /terminal:LOGIN --disable-ssl --localhost-only"
Finally, restart the deamon:
/etc/init.d/shellinabox restart
And check if all went well:
/etc/init.d/shellinabox status
You should see:
Shell In A Box Daemon is running
Another way to verify is to check the open ports:
netstat -ntl
You should see:
Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 127.0.0.1:4200 0.0.0.0:* LISTEN
Setting up Lighttpd as a proxy
Shell In A Box runs on port 4200 by default. Although this can be changed to a more common 80 or even 443, this is not what I want. I decided to integrate it with another webserver, to be able to combine other services and use just one url (and one SSL certificate). Since the Raspberry Pi isn’t that powerful, I choose Lighttpd.
apt-get instal lighttpd cd /etc/lighttpd/conf-enabled ln -s ../conf-available/10-proxy.conf
This installs Lighttpd and enables Proxy support. Now add the Proxy config:
vim /etc/lighttpd/lighttpd.conf
And add:
proxy.server = (
"/terminal" =>
( (
"host" => "127.0.0.1",
"port" => 4200
) )
)
Save and restart Lighttpd:
/etc/init.d/lighttpd restart
Connect to http://pi.example.org/terminal and your Shell In A Box terminal should appear.
Although this is cool already, we’re not quite there. No one will SSH on an unencrypted web page, right? So, we’ll configure an SSL certificate to enable encryption. For double safety, we’ll also set a username/password on the web page. One then needs to know this password to access the login promt, and needs a valid local username/password to really use the terminal.
Adding encryption with SSL
By using a HTTPS-url, our traffic is encrypted. Let’s generate a private key (and remove the passphrase):
openssl genrsa -des3 -out pi.example.org.key 2048 cp -pr pi.example.org.key pi.example.org.key.passwd openssl rsa -in pi.example.org.key.passwd -out pi.example.org.key
If you do not remove the passphrase, you will need to type it every time you start the web server. To request a SSL-certificate, you need to supply a CSR (Certificate Signing Request) and send that to a SSL provider such as Thawte or Verisign.
openssl req -new -key pi.example.org.key -out pi.example.org.csr
To be able to continue now, let’s self-sign the certificate:
openssl x509 -in pi.example.org.csr -out pi.example.org.pem -req -signkey pi.example.org.key -days 365 cat pi.example.org.key >> pi.example.org.pem
A self-signed certificate will display a warning in our browser, but that’s ok for now. Once the real certificate comes back from our SSL provider, it’s easy to replace it. The warning will then disappear.
Time to tell Lighttpd about our certificate:
vim /etc/lighttpd/lighttpd.conf
Add these lines:
$SERVER["socket"] == "10.0.0.10:443" {
ssl.engine = "enable"
ssl.pemfile = "/etc/lighttpd/ssl/pi.example.org/pi.example.org.pem"
server.name = "pi.example.org"
server.document-root = "/home/lighttpd/pi.example.org/https"
server.errorlog = "/var/log/lighttpd/pi.example.org_serror.log"
accesslog.filename = "/var/log/lighttpd/pi.example.org_saccess.log"
}
And restart Lighttpd:
/etc/init.d/lighttpd restart
Now Shell In A Box should be available on: https://pi.example.org/terminal
Enhancing security by adding HTTP-auth
Since the /terminal page now makes an actual terminal available to web users, I added an extra password for security. You can use the ‘HTTP Auth’ method for this. It will pop up a message box that requires an valid username/password before the /terminal page is shown.
First enable the module:
cd /etc/lighttpd/conf-enabled ln -s ../conf-available/05-auth.conf
Then extend the config of the virtual host config you created above. The final result should be:
$SERVER["socket"] == "10.0.0.10:443" {
ssl.engine = "enable"
ssl.pemfile = "/etc/lighttpd/ssl/pi.example.org/pi.example.org.pem"
server.name = "pi.example.org"
server.document-root = "/home/lighttpd/pi.example.org/https"
server.errorlog = "/var/log/lighttpd/pi.example.org_serror.log"
accesslog.filename = "/var/log/lighttpd/pi.example.org_saccess.log"
auth.debug = 2
auth.backend = "htpasswd"
auth.backend.htpasswd.userfile = "/etc/lighttpd/shellinabox-htpasswd"
auth.require = ( "/terminal/" =>
(
"method" => "basic",
"realm" => "Password protected area",
"require" => "user=remibergsma"
)
)
}
Reload Lighttpd to make the changes active:
/etc/init.d/lighttpd reload
To set a password:
apt-get install apache2-utils htpasswd -c -m /etc/lighttpd/shellinabox-htpasswd remibergsma
You can enter multiple users, just remember to remove the ‘-c’ flag when adding more users, as this overwrites the current file.
When you visit https://pi.example.org/terminal you will need to enter a valid username and password, before the page loads.
The final result: SSH in a browser window!
You should now be able to use a terminal via your own protected webpage. It’s mostly like a real terminal/SSH session but from a browser. Wow 🙂

Shell In A Box in action
I always use GNU Screen, so I know for sure my commands keep running whatever happens.

Using GNU Screen in a browser
OpenVPN is great, it allows for easy access in a secure way. But how do you keep it secure? I mean, what if someone leaves your company? Do you disable access to the OpenVPN server? You should! In this blog I’ll show you how to do it.
A feature called revoking exists in OpenVPN. Revoking a certificate means to invalidate a previously signed certificate so that it can no longer be used for authentication purposes. For this to work, we need to tell the OpenVPN server which certificates are no longer valid.
All connecting clients will then have their client certificates verified against the so-called CRL (Certificate Revoking List). Any positive match will result in the connection being dropped. Your former employees will no longer have access, even if they still have their certificates.
Creating a certificate to test with
Before we start, let’s generate a dummy certificate for testing purposes:
cd /etc/openvpn/easy-rsa/2.0/ . ./vars ./build-key unwanted-client-name
Verify you can connect to the OpenVPN server using this certificate. Refer to my earlier post for more info. Now that this works, I’ll show you how to revoke this certificate so you will no longer be able to connect.
Revoking a certificate
To revoke a certificate, we’ll use the ‘easy-rsa’ toolset.
cd /etc/openvpn/easy-rsa/2.0
If it’s not there, look at the OpenVPN examples and copy it:
cp -R /usr/share/doc/openvpn/examples/easy-rsa /etc/openvpn cd /etc/openvpn/easy-rsa/2.0
Run this command to revoke the certificate called ‘unwanted-client-name’:
./revoke-all unwanted-client-name
You should see output similar to this:
Using configuration from /etc/openvpn/easy-rsa/2.0/openssl-1.0.0.cnf Revoking Certificate 03. Data Base Updated Using configuration from /etc/openvpn/easy-rsa/2.0/openssl-1.0.0.cnf unwanted-client-name.crt: C = NL, ST = ZH, L = City, O = Name, OU = pi.example.org, CN = unwanted-client-name, name = unwanted-client-name], emailAddress = [email protected] error 23 at 0 depth lookup:certificate revoked
Note the “error 23” in the last line. That is what you want to see, as it indicates that a certificate verification of the revoked certificate failed.
The index.txt file on keys directory will be updated. You’ll see an ‘R’ (for Revoked) on the first column from the left for your user when you run this:
cat keys/index.txt
You can also examine the CRL to see what’s in there:
openssl crl -in keys/crl.pem -text
Now copy the crl.pem file to the OpenVPN config directory:
cp keys/crl.pem /etc/openvpn/
Whenever you revoke a certificate, you’ve to copy it to the OpenVPN server.
Note: The CRL file is not secret, and should be made world-readable so that the OpenVPN daemon can read it after root privileges have been dropped.
Enable revoking support
Before it works, we need to setup the OpenVPN server to add support for revoking certificates. You’ve to do this only once.
Add the folowing line to the OpenVPN server config:
vim /etc/openvpn/server.conf
crl-verify /etc/openvpn/crl.pem
Reload the OpenVPN server to activate the revoke setting:
/etc/init.d/openvpn reload
Testing the revoked certificate
The final test: try to login again using the ‘unwanted-client-name’ certificate. It will not work anymore!
By revoking users, you disallow access to your OpenVPN server for users that previously had access. This should be done as soon as an user no longer needs access, as it is an important security feature.
When you create firewall rules with iptables on Linux, you want to make them persistent over reboot, because they are not by default. Different Linux distributions have different methods of achieving this, although the basics are similar. I’ve been working with Debian, Red Hat Enterprise Linux and SUSE Linux Enterprise Server and in this blog I’ll describe how to configure each of them to save your iptables rules across reboots.
First the good news: the iptables package, the administration tool for packet filtering and NAT, always ships with Linux distributions. The package also includes the ‘iptables-save‘ and ‘iptables-restore‘ tools. These do what you might already expect from their names: save or restore iptables rules. ‘iptables-save‘ outputs to stdout, which you can save to a file:
iptables-save > /etc/iptables/rules
To load these again:
iptables-restore < /etc/iptables/rules
These really are the basics that work across Linux distributions and that you can use in your custom boot scripts. In addition to this, each Linux distribution has its own way to make this process easier.
Red Hat Enterprise Linux (RHEL):

RHEL (and the same counts for CentOS and Fedora) has some built in mechanism to help automate this. First of all, there are some settings in ‘/etc/sysconfig/iptables-config‘:
IPTABLES_SAVE_ON_STOP=”yes”
IPTABLES_SAVE_ON_RESTART=”yes”
You can set them to “yes” to have persistent iptables rules. In fact, there are many more settings in that file that allow for finer control. That’s all, since the rest is handled automatically.
At any time it’s possible to save the current state. Just run:
service iptables save
And it will, like on reboot, save the rules to: ‘/etc/sysconfig/iptables‘. Pretty easy and pretty powerful!
SUSE Linux Enterprise Server (SLES 11):
SLES (and the same counts for OpenSUSE) is yet another story. SLES 11 now ships with SUSE Firewall. Instead of defining the rules yourself, you tell Yast what you want to achieve and it generates the needed iptables rules for you. Although SUSE Firewall does allow you to add custom rules, it isn’t really designed for it. The tool is pretty nice though, because it integrates fully with Yast and allows for easy maintenance of rules. When you install a package, it automatically opens the associated port, for example.
This all might seems a bit scary for us sysadmins, right?! Don’t worry, it’s still possible to manage rules on your own by disabling SUSE Firewall. But have a look at it first, as you might as well like it.
To start the SUSE Firewall admin module, run:
yast2 firewall
The interface is pretty self-explaining. Afterwards, to activate the changes run:
SuSEfirewall2
It’s even possible to by-pass Yast, and edit the config file directly. It’s safe to combine the two methods, no problem.
vim /etc/sysconfig/SuSEfirewall2
For example, to open a port you’d edit the ‘FW_SERVICES_EXT_TCP’ variable. Just make a list (space separated) with protocols you want to allow. These protocols refer to files in ‘/etc/sysconfig/SuSEfirewall2.d’.
Like with using Yast, activate the changes when you’re done.
SuSEfirewall2
I’ve used it for some time and it’s actually pretty easy. It just depends on the project whether or not to use it, I guess.
Debian
When I was using Debian (same counts for Ubuntu as well), I used to create a small shell script and place it in ‘/etc/network/if-pre-up.d’. Just before the network interface is brought up, the iptables rules will be restored. The idea is to do the same when the interface goes down (use the ‘/etc/network/if-post-down.d’ folder to place the script in). Using these thechniques, you can create something and have fine control over it.
Recently I heard about a tool called ‘iptables-persistent’ that can automate this out-of-the-box. Here’s the package description:
iptables-persistent - boot-time loader for iptables rules: Current iptables rules can be saved to the configuration file '/etc/iptables/rules.v4'. These rules will then be loaded automatically during system startup.
To install it:
sudo apt-get install iptables-persistent
During install, the program asks to save both ipv4 and ipv6 iptables rules. Please note this counts for Wheezy, the current stable release uses the file ‘/etc/iptables/rules’.
To manually save the iptables rules, run:
/etc/init.d/iptables-persistent save
Although this should be done automatically when you reboot. It looks like the Red Hat way of doing things, but just with an extra package installed.
Conclusion:
iptables all over the place, just with different tooling to automate it 🙂