#!/bin/blog

April 24, 2009

OpenSSH connection multiplexing

Filed under: Security, UNIX & Linux — Tags: , , — martin @ 6:44 am

The Challenge

I was in touch with a developer the other day who used SSH to programmatically connect to a remote machine where he would start some kind of processing job. Unfortunately, he was in trouble when he wanted to kill the remote process. Killing the local SSH client would leave his job active. He claimed that there used to be some sort of signal forwarding feature in OpenSSH on the machine where he had developed his application in OpenSSH 3.x days, but this feature seems to have been removed by now.

I wasn’t able to confirm anything of this, but this gentleman’s problem got me curious. I started to wonder: Is there some kind of sideband connection that I might use in SSH to interact with a program that is running on a remote machine?

The first thing I thought of were port forwards. These might actually be used to maintain a control channel to a running process on the other side. On the other hand, sockets aren’t trivial to implement for a /bin/ksh type of guy, such as the one I was dealing with. Also, this approach just won’t scale. Coordination of local and remote ports is bound to turn into a bureaucratic nightmare.

I then started to skim the SSH man pages for anything that looked like a “sideband”, “session control” or “signaling” feature. What I found, were the options ControlMaster and ControlPath. These configure connection multiplexing in SSH.

Proof Of Concept

Manual one-shot multiplexing can be demonstrated using the -M and -S options:

1) The first connection to the remote machine is opened in Master mode (-M). A UNIX socket is specified using the -S option. This socket enables the connection to be shared with other SSH clients:

localhost$ ssh -M -S ~/.ssh/controlmaster.test.socket remotehost

2) A second SSH session is attached to the running session. The socket that was opened before is specified with the -S option. The remote shell opens without further authentication:

localhost$ ssh -S ~/.ssh/controlmaster.test.socket remotehost

The interesting thing about this is that we now have two login sessions running on the remote machine, who are children of the same sshd process:

remotehost$ pstree -p $PPID
sshd(4228)─┬─bash(4229)
           └─bash(4252)───pstree(4280)

What About The Original Challenge?

Well, he can start his transaction by connecting to the remote machine in Master mode. For simplicity’s sake, let’s say he starts top in one session and wants to be able to kill it from another session:

localhost$ ssh -t -M -S ~/.ssh/controlmaster.mytopsession.socket remotehost top

Now he can pick up the socket and find out the PIDs of all other processes running behind the same SSH connection:

localhost$ ssh -S ~/.ssh/controlmaster.mytopsession.socket remotehost 'ps --ppid=$PPID | grep -v $$'
  PID TTY          TIME CMD
 4390 pts/0    00:00:00 top

This, of course, leads to:

localhost$ ssh -S ~/.ssh/controlmaster.mytopsession.socket remotehost 'ps --no-headers -o pid --ppid=$PPID | grep -v $$ | xargs kill'

Then again, our shell jockey could just use PID or touch files. I think this is what he’s doing now anyway.

Going Fast And Flexible With Multiplexed Connections

With my new developer friend’s troubles out of the way, what else could be done with multiplexed connections? The SSH docs introduce “opportunistic session sharing”, which I believe might actually be quite useful for me.

It is possible to prime all SSH connections with a socket in ~/.ssh/config. If the socket is available, the actual connection attempt is bypassed and the ssh client hitches a ride on a multiplexed connection. In order for the socket to be unique per multiplexed connection, it should be assigned a unique name through the tokens %r (remote user), %h (remote host) and %p (destination port):

ControlPath ~/.ssh/controlmaster.socket.%r.%h.%p
# Will create socket as e.g.: ~/.ssh/controlmaster.socket.root.remotehost.example.com.22

If there is no socket available, SSH connects directly to the remote host. In this case, it is possible to automatically pull up a socket for subsequent connections using the following option in ~/.ssh/config:

ControlMaster auto

So Where’s The Actual Benefit?

I use a lot of complex proxied SSH connections who take ages to come up. However, connecting through an already established connection goes amazingly fast:

# Without multiplexing:
localhost$ time ssh remotehost /bin/true
real    0m1.376s
...
# With an already established shared connection:
localhost$ time ssh remotehost /bin/true
real    0m0.129s
...

I will definitely give this a try for a while, to see if it is usable for my daily tasks.

Update, 2009/05/04: No, it isn’t. Disconnecting slave sessions upon logout of the master session are too much of a nuisance for me.

February 27, 2009

Packaging OpenSSH on CentOS

Filed under: Security, UNIX & Linux — Tags: , , , , — martin @ 8:29 am

My article on chrooted SFTP has turned out to be the most popular article on this blog. What a pity that its “companion article” on building current OpenSSH on CentOS 5 is such a bloody hell of a mess.

Fortunately, reader Simon pointed out a really simple method for building RPMs from current OpenSSH sources in a comment. We had the chance to try this out in a production deployment of chrooted SFTP the other day, and what can I say? It just works(tm)! Thanks a lot, dude! :-)

# yum install gcc
# yum install openssl-devel
# yum install pam-devel
# yum install rpm-build

It certainly doesn’t hurt to make the GPG check a habit:

# wget http://ftp.bit.nl/mirror/openssh/openssh-5.2p1.tar.gz
# wget http://ftp.bit.nl/mirror/openssh/openssh-5.2p1.tar.gz.asc
# wget -O- http://ftp.bit.nl/mirror/openssh/DJM-GPG-KEY.asc | gpg –-import
# gpg openssh-5.2p1.tar.gz.asc
gpg: Signature made Mon 23 Feb 2009 01:18:28 AM CET using DSA key ID 86FF9C48
gpg: Good signature from "Damien Miller (Personal Key) "
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: 3981 992A 1523 ABA0 79DB FC66 CE8E CB03 86FF 9C48

Prepare, build and install the RPM. Disable the building of GUI components in the spec file. We don’t need these on a server:

# tar zxvf openssh-5.2p1.tar.gz
# cp openssh-5.2p1/contrib/redhat/openssh.spec /usr/src/redhat/SPECS/
# cp openssh-5.2p1.tar.gz /usr/src/redhat/SOURCES/
# cd /usr/src/redhat/SPECS
# perl -i.bak -pe 's/^(%define no_(gnome|x11)_askpass)\s+0$/$1 1/' openssh.spec
# rpmbuild -bb openssh.spec
# cd /usr/src/redhat/RPMS/`uname -i`
# ls -l
-rw-r--r-- 1 root root 275808 Feb 27 08:08 openssh-5.2p1-1.x86_64.rpm
-rw-r--r-- 1 root root 439875 Feb 27 08:08 openssh-clients-5.2p1-1.x86_64.rpm
-rw-r--r-- 1 root root 277714 Feb 27 08:08 openssh-server-5.2p1-1.x86_64.rpm
# rpm -Uvh openssh*rpm
Preparing... ########################################### [100%]
1:openssh ########################################### [ 33%]
2:openssh-clients ########################################### [ 67%]
3:openssh-server ########################################### [100%]
# service sshd restart

The RPM should install cleanly on CentOS 4. On CentOS 5, after installation, service ssh restart throws a warning that initlog is obsolete. I work around this by keeping a copy of the old /etc/init.d/sshd and restoring it after RPM installation.

February 14, 2009

Re-Layering LVM encryption

Filed under: Security, UNIX & Linux — Tags: , , — martin @ 11:48 pm

In an earlier article, I had promised live migration of LVM data to encrypted storage. I was able to acquire an external SATA disk for my backup server today, so here we go. :-)

crypt-lvm1

The backup server is running headless, so I opted to store the key locally for now. Yes, I’m a moron. But hey, at least it’s not on the same medium.

# dd if=/dev/urandom of=/etc/luks.key count=256 ; chmod 600 /etc/luks.key

As long as the disk isn’t the only one, I can’t predict the device name it will come up as. Thus, it is referenced by its udev ID when formatting it with LUKS:

# cryptsetup luksFormat /dev/disk/by-id/scsi-SATA_WD_My_Book_WD-WCAU123-part1 /etc/luks.key

Open the new LUKS device:

# cryptsetup luksOpen -d /etc/luks.key /dev/disk/by-id/scsi-SATA_WD_My_Book_WD-WCAU123-part1 pv_crypt_1

The entry in /etc/crypttab makes the encrypted device come up on boot:

/etc/crypttab:

pv_crypt_1 /dev/disk/by-id/scsi-SATA_WD_My_Book_WD-WCAU123-part1 /etc/luks.key luks

Create a new Physical Volume on the crypted device:

# pvcreate /dev/mapper/pv_crypt_1

Now the Volume Group can be extended with the new PV:

# vgextend datavg /dev/mapper/pv_crypt_1

I rebooted at this point, in order to see if everything would come up as expected.

The new PV is now visible:

# pvs
  PV         VG     Fmt  Attr PSize   PFree
  /dev/dm-0  datavg lvm2 a-   931.51G 931.51G
  /dev/sdb1  datavg lvm2 a-   465.76G      0

The next step is to migrate the VG content to the new PV. Migration will take a very long time if the disk is full, so you may want to use a screen session for this.

# pvmove -v  /dev/sdb1

This is a classical LVM operation that may be cancelled at any time and picked up later. In fact, my Promise SATA driver crashed hard in the middle of the operation, and everything went along fine after a kernel upgrade.

When pvmove is done, throw out the original PV from the volume group:

# vgreduce datavg /dev/sdb1

The Volume Group is now on encrypted storage.

January 18, 2009

Managing encrypted logical volumes

Filed under: Security, UNIX & Linux — Tags: , , — martin @ 1:32 pm

Worked on this with G. the other day.

Create the underlying logical volume:
lvcreate -n datalv_crypted -L 1G vg00

Initialize a LUKS crypto device on the logical volume:
cryptsetup luksFormat /dev/vg00/datalv_crypted

If you have lost your mind and want to keep the passphrase in a file (which is what G.’s weirdo client had asked for):
dd if=/dev/urandom of=/etc/i_am_dumb count=256
cryptsetup luksFormat /dev/vg00/datalv_crypted /etc/i_am_dumb

Bring up the crypto device from the encrypted logical volume:
cryptsetup luksOpen /dev/vg00/datalv_crypted data # optionally -d /etc/i_am_dumb

Create a file system on the crypto device, /dev/mapper/data, which has now sprung to life:
mkfs.ext3 /dev/mapper/data

Enter the crypto device in /etc/fstab:
/dev/mapper/data /data ext3 defaults 0 0

Don’t forget to create the mount point:
mkdir /data

Enter the encrypted logical volume in /etc/crypttab. Substitute “none” with /etc/i_am_dumb if you are keeping the passphrase on the system.
data /dev/vg00/datalv_crypted none luks

Reboot. You will be prompted for the passphrase on bootup, unless you’re keeping it in a file. The new file system will be mounted on /data.

The usual process for resizing file systems now has to be extended by an additional step:

lvresize -L +1G /dev/vg00/datalv_crypted
cryptsetup resize /dev/mapper/data
resize2fs /dev/mapper/data

That’s all there is to it. In another installment, I will hopefully write about encrypted physical volumes, allowing live migration of an entire volume group to encrypted storage during full operation. :-)

With the technical details out of the way, some additional words about keeping the passphrase on-disk:

If you work for someone who wants this, he’s not neccessarily an idiot, but maybe just a bit naive. It is your duty as the expert to explain why keeping the passphrase in-band with the encrypted data is nothing more than just a waste of CPU cycles. Seriously. This, G., means you. ;-)

October 20, 2008

OpenSSH: Going flexible with forced commands

Filed under: Security, UNIX & Linux — Tags: , — martin @ 9:32 am

As we all know, it is possible to use SSH not only for obtaining an interactive login session on a remote machine, but also for executing commands remotely. For instance, the following command will log on to myserver.example.com, execute “uname -a” and return to the local shell:

ssh myserver.example.com uname -a

(The local SSH client returns the exit code from the remote command, if you’re into this kind of detail.)

You might have some users (or scheduled automatisms) that you don’t want to be able to log on to that machine at all, but who should be permitted to execute only a given command. In order to achieve this, you can configure key-based authentication. Once this has been done, the key can be prefixed with a number of configuration options. Using one of these options, it is possible to enforce execution of a given command when this key is used for authentication.

In this example from ~/.ssh/authorized_keys, the user wants to look at the process list, so we set the command to “ps -ef”.

command="/bin/ps -ef"

Using this, when the user tries to log in, or tries to execute an arbitrary command, “/bin/ps -ef” is executed instead and the SSH session terminates.

In addition to enforcing a command, it is advisable to disable a number of advanced SSH features, such as TCP and X11 forwarding. Assignment of a pseudo terminal to the user’s SSH session may also be suppressed, by adding a number of additional configuration options next to the forced command:

no-port-forwarding,no-X11-forwarding,no-pty

Here’s what a full entry from ~/.ssh/authorized_keys might look like:

command="/bin/ps -ef",no-port-forwarding,no-X11-forwarding,no-pty ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAp0KMipajKK468mfihpZHqmrMk8w+PmzTnJrZUFYZZNmLkRk+icn+m71DdEHmza2cSf9WdiK7TGibGjZTE/Ez0IEhYRj5RM3dKkfYqitKTKlxVhXNda7az6VqAJ/jtaBXAMTjHeD82xlFoghLZOMkScTdWmu47FyVkv/IM1GjgX/I8s4307ds1M+sICyDUmgxUQyNF3UnAduPn1m8ux3V8/xAqPF+bRuFlB0fbiAEsSu4+AkvfX7ggriBONBR6eFexOvRTBWtriHsCybvd6tOpJHN8JYZLxCRYHOGX+sY+YGE4iIePKVf2H54kS5UlpC/fnWgaHbmu/XsGYjYrAFnVw== Test key

This is quite nice: We have successfully limited this user to requesting a process list.

This is called an SSH forced command.

So much for the introduction. :-D

Here’s what I’m really getting at today – What, if we want the user to not only execute a single command, but a number of commands, such as:

- Show process list (ps)
- Show virtual memory statistics (vmstat)
- Stop and start the print server (/etc/init.d/cupsys stop/start)

Following the approach described above, this would give us four key pairs, four entries in ~/.ssh/authorized_keys, and four entirely different invocations of SSH on the client side, each of them using a dedicated private key. In other words: An administrative nightmare.

This is where the environment variable $SSH_ORIGINAL_COMMAND comes in. (This nice facility was pointed out to me last week by G., who had read about it somewhere but wondered what it might be useful for.)

Until now, all we know is that with a forced command in place, the SSH server ignores the command requested by the user. This is not entirely true, though. The SSH server does in fact remember the command that was requested, stores it in $SSH_ORIGINAL_COMMAND and thus makes it available within the environment of the forced command.

With this in mind, it is possible to allow more flexibility inside forced commands, without the need to go crazy with countless key pairs. Instead, it is possible to just create a wrapper script that is called as the forced command from within ~/.ssh/authorized_keys and decides what to do, based on the content of $SSH_ORIGINAL_COMMAND:

#!/bin/sh
# Script: /usr/local/bin/wrapper.sh 

case "$SSH_ORIGINAL_COMMAND" in
	"ps")
		ps -ef
		;;
	"vmstat")
		vmstat 1 100
		;;
	"cups stop")
		/etc/init.d/cupsys stop
		;;
	"cups start")
		/etc/init.d/cupsys start
		;;
	*)
		echo "Sorry. Only these commands are available to you:"
		echo "ps, vmstat, cupsys stop, cupsys start"
		exit 1
		;;
esac

It is important to be aware of potential security issues here, such as the user escaping to a shell prompt from within one of the listed commands. Setting the “no-pty” option already makes this kind of attack somewhat difficult. In addition, some programs, such as “top”, for example, have special options to run them in a “secure” read-only mode. It is advisable to closely examine all programs that are called as SSH forced commands for well-meant “backdoors” and to find out about securing them.

It’s up to you to decide based on your own situation, whether you want to run this wrapper as the root user or if you prefer to use password-less “sudo” commands to raise privileges where needed.

If you encounter problems while debugging $SSH_ORIGINAL_COMMAND, please make absolutely sure that you are authenticating with the correct key. I found it helpful to unset SSH_AUTH_SOCK in the window where I do my testing, in order to prevent intervention from identies stored in the SSH agent.

October 10, 2008

Untote Exploits

Filed under: Security, UNIX & Linux — Tags: , , , — martin @ 5:55 am

Jahrelang habe ich auf dem K. herumgehackt, weil “sein” IPS immer Verbindungen unterbrochen hat, nachdem es Bytefolgen auf der Leitung gesehen hatte, mit denen man vor etlichen Jahren mal irgendwelche archaischen Exploits (konkret erlebtes Beispiel: Sendmail decode vulnerability) triggern konnte. Denn mal ehrlich: Wie obskur kann’s noch werden?

Heute bin ich in gewisser Weise einen Schritt weiter, denn bei einem Kunden wurde ein SLES9 aus dem Internet gecrackt, weil der Angreifer sich über einen PHP-Exploit die /etc/passwd herunterladen konnte und darin Passwort-Hashes vorgefunden hat, die ein Administrator beim Anlegen von Usern per Copy&Paste dort eingebaut hat. Die hat er dann auf dem üblichen Weg mit etwas Geduld per Brute-Force geknackt. Ein Szenario aus den 1980ern. Ekelhaft.

August 24, 2008

Port 80 und 443 unter Windows Vista

Filed under: Security — Tags: , — martin @ 8:19 am

Irritation beim Portscan:

$ nmap macbook

Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2008-08-24 09:08 CEST
Interesting ports on macbook (192.168.1.207):
Not shown: 1678 filtered ports
PORT    STATE SERVICE
80/tcp  open  http
443/tcp open  https

Nmap finished: 1 IP address (1 host up) scanned in 31.606 seconds

Und der Verursacher:

Ächz!™

July 10, 2008

Verisign und OCSP

Filed under: Security — Tags: , , , , — martin @ 9:36 pm

Was mir heute nicht so gut in den Kram gepaßt hat:

$KUNDE warf mir nochmal 50 SSL-Zertifikate vor die Füße, zwecks Überprüfung, von denen 38 für das Debian-SSL-Problem empfänglich waren. Aber ich hab ja mittlerweile Routine.

Also wurden neue CSRs generiert, welche er bei Verisign (RSA/”Secure Server Certification Authority”) zum Re-Issue eingereicht hat. Minuten später kam der erste mit einer Firefox-Fehlermeldung um die Ecke:

Die verantwortliche Konfigurationsoption war dann auch schnell identifiziert:

Willkommen im Dilemma. So schwer es mir fällt, zu bestreiten, daß diese Voreinstellung in Firefox 3.0 auf den Tag genau zur rechten Zeit kommt, so unangebracht finde ich es, daß Verisign ein Zertifikat, dessen Austausch es gerade mal so mit Ach und Krach in die Mailbox der Administratoren geschafft hat, sofort per OCSP als gesperrt propagiert.

Gerade weil es jetzt so weit ist, daß OCSP, das Online Certificate Status Protokoll, tatsächlich genutzt wird, wäre eine gewisse Galgenfrist von mindestens 1 Tag bis vielleicht 1 Woche mehr als angemessen. Insbesondere bei einer Massenaktion mit einem Umfang von mehreren Dutzend Zertifikaten ist mir persönlich nämlich schleierhaft, wie man die Zertifikate im Rahmen von Change-Prozessen derart schnell auf die Produktivserver katapultieren soll.

Wenn man nochmal 30 Sekunden drüber nachdenkt, kommt man übrigens zur Erkenntnis, daß es auch mit einem einzigen Zertifikat kaum sauber hinzubekommen ist. Auf einer hochgradig produktiven SSL-Site muß man, wenn die CA einen OCSP Distribution Point bereitstellt, in Zukunft auf den Re-Issue verzichten und additiv ein neues Zertifikat dazukaufen, um es überhaupt ohne Ausfall tauschen zu können. Ob das wirklich im Sinne des Erfinders ist?

July 2, 2008

SGC(“Step-Up”)-Zertifikate

Filed under: Security — Tags: — martin @ 10:12 pm

Verlautbarung von heute an einen Kunden, der SGC-Zertifikate einsetzen will, um möglichst lückenlos alle Browser zu unterstützen:

“Vom Einsatz von Step-Up/SGC-Zertifikaten, die die Verwendung von Browsern ermöglichen, die der vor dem Jahr 2000 gültigen Exportbeschränkung der USA unterliegen, wird abgeraten. Es wird empfohlen, die Unterstützung veralteter Browser, für die keinerlei Updates mehr verfügbar sind, aus Sicherheitsgründen einzustellen.”

Mit den SGC-Zertifikaten (“Server Gated Cryptography“), je nach Marketingmasche auch “Step-Up” genannt, ist das so: Bis Anfang 2000 gab es seitens der USA diese beschränkte Exportbeschränkung, nach der “starke” Verschlüsselung als Kriegswaffe zu behandeln war und deshalb nur unter strengsten Auflagen aus den USA ausgeführt werden durfte. Nun kamen aber alle halbwegs relevanten Web-Browser aus USA (Netscape, Internet Explorer). Wegen der Ausfuhrbeschränkung war in diesen die Schlüssellänge für SSL auf 40 Bit begrenzt. Weil man aber auch schon in den 1990ern Knete mit E-Business machen wollte, gab es verschiedene CAs, die mit Segen der US-Regierung für Banken & Co. Zertifikate ausstellten, bei deren Anblick der Browser seine Exportbeschränkung vergaß und auf 128 Bit Schlüssellänge umschaltete. Das war dann die “Step-Up”-Security.

Die Exportbeschränkung ist 2000 gefallen, aber die CAs bieten die SGC-Zertifikate noch immer an und lassen sie sich fürstlich bezahlen. Thawte nimmt für ein Jahr Laufzeit z.B. lässige 699 US-Dollar und haut mächtig auf die Sahne:

Provide the best encryption available for each site visitor. Without an SGC-enabled certificate on your site, your visitors using certain older browsers and many Windows 2000 users will only receive 40- or 56-bit encryption.

Ich halte ja nicht extrem viel von diesem hysterischen Getue, nach dem jedes irgendwo greifbare Security-Update sofort installiert werden muß, auch wenn es für einen obskuren Teil des Betriebssystems gilt, den man im ganzen Leben noch nicht benutzt hat. Hier geht es nun aber um Web-Browser und somit um die Killerapplikation der letzten Dekade. Wer SGC einsetzt, unterstützt aktiv folgende Browserversionen:

  • Internet Explorer 5 (Aktuelle Version: 7)

  • Netscape 4 (Aktuelle Version: 9, Entwicklung ist eingestellt)
  • Opera 3 (Aktuelle Version: 9)

Als gut abgehangener Linux-User bin ich es ja gewohnt, jahrelang aktiv von irgendwelchen Webseiten ausgesperrt worden zu sein. Solche Unverschämtheiten vergißt man nicht. In diesem Fall ist es allerdings mehr als angebracht, die eigenen Kunden vorm Gebrauch dieser antiken Exploit-Schleudern zu schützen.

Ich mußte mich da auch erstmal reinlesen, da ich mich nicht erinnern kann, selbst Erfahrungen damit gesammelt zu haben, abgesehen von einem total inoffizellen Patch für den Netscape Navigator, mit dem man diese Exportgeschichte irgendwie global abschalten konnte.

Der Kunde von oben zeigt auf seiner Homepage übrigens ein Flash-Video an und weist ausdrücklich darauf hin, daß die Seite nur mit IE ab Version 6, Netscape ab Version 6 oder Mozilla ab Version 1.0 benutzbar ist. Das ist dann der Punkt, an dem die Sache ins Absurde übergeht. ;-)

June 21, 2008

Surfin’ the post 5/13 world.

Filed under: Security — Tags: , , , — martin @ 11:27 pm

Das audit-ssl-Script (.tar.gz) ist funktional in der Lage, Seiten mit angreifbaren SSL-Zertifikaten zu erkennen. Komfortabler und plattformübergreifend tut es aber die SSL Blacklist Extension für den Firefox:

Auch zu empfehlen als kleiner Warnschuß an Anwender, die sich weigern, Zertifikate auszutauschen: “Firefox zeigt bereits eine Warnmeldung an. Was wirst Du Deinen Kunden erzählen, wenn der Internet Explorer das nach dem nächsten Microsoft-Patchday ebenfalls macht?”

Older Posts »

Blog at WordPress.com.