A blog on Computer Science, Security, Programming, and more...

HeapSpray Blog » Category: Linux


Using socat To Proxy SSL Connections

Written by Matt

socat is a greatly versatile networking tool, though the man page is ridiculous and it's hard to find an example of exactly what you want to do if you search since socat can do so many things, usually the results you get are close but not really what you want.

Something I need to do often is either intercept SSL connections and be able to analyze them on a packet level, or provide SSL capabilities to a program that doesn't support the ability to communicate over SSL / encrypted streams. Here is the socat command to be able to do that:

socat TCP-LISTEN:LPORT,fork openssl:IP:PORT,verify=0

This binds a listening socket to local port LPORT, and tunnels that request through to IP:PORT over an SSL connection. So if this was to proxy an HTTPS request, you would connect to and it would be redirected to domain.com:443 with SSL by socat, but the traffic from the browser to socat would still be in plaintext for you to analyze. You would need to set a custom Host: directive to make sure it all works.

This is also useful if, say, you have written some IRC bot without SSL support, but you want it to be able to connect securely without having to add in that support yourself, and you're not using a language where you can just import ssl, just run the command above with IP/PORT as the IP of IRC server on the SSL PORT, and connect your bot to localhost:LPORT and it will connect securely to the IRC. You would probably want to actually verify the certificate in this case.


Prevent Program From Accessing The Network in Linux

Written by Matt

I've just recently found out Linux supports namespaces on recent kernels, through the program unshare. As the name implies, it unshares namespaces from the parent and allows you to run programs with restricted access.

The program can simply be used as follows:

# unshare -n -- ping
connect: Network is unreachable

The '--' signifies that all arguments beyond that point are no longer arguments to 'unshare' but to the program you want to execute and its arguments. As you can see, ping fails to reach even localhost, because this creates a new network namespace (option -n in unshare) that has no devices and no networking setup - it's totally blank.

One problem with this is that you need to run the command itself as root, because to run 'unshare' you need CAP_SYS_ADMIN capabilities, which is basically equivalent to root, but you may not want to run the restricted process as root and certainly not with CAP_SYS_ADMIN capabilities, for obvious reasons (as it will just be able to choose another namespace itself if it wants to). Therefore, you can run the command as follows:

$ su -c 'unshare -n -- su - YOUR_USER -c "ping"'

A little obtuse, but this uses 'su' to run 'unshare' as root, then uses 'su' within unshare's created namespace to demote the privileges down to YOUR_USER, and then runs the command "ping" as YOUR_USER. It can be turned into a script for convenience:


if [ "$#" -ne 2 ]; then
    echo "Usage: nonetwork.sh <user> <command>"

su -c "unshare -n -- su - $1 -c \"$2\""

Save this as nonetwork.sh and place it in /usr/local/bin, and then you can run it as follows:

$ nonetwork.sh USER "ping"
Password: [Enter root password]
connect: Network is unreachable

Do note that you need a relatively recent kernel, and your kernel needs to be compiled with CONFIG_NET_NS=y -- from a little research it seems "full" support for these operations was added after kernel version 3.4.x, so it might not work on server distributions like CentOS which still use the 2.6.x series kernel.

Glad to see Linux is getting namespace support. I wonder when it happened?


Creating Encrypted Virtual Volumes in Linux

Written by Matt

Here's how to create a "drive inside a file", the way TrueCrypt does, but using tools that are already included by default on most Linux distributions.

First, create the file that you will use as the drive using the command dd:

dd if=/dev/zero of=drive.bin bs=1048576 count=1024

The above creates a 1GB file called "drive.bin" filled with zeros, the block size being 1MB (1024*1024), and the number of blocks being 1024, which is exactly 1GB.

All the steps now will need to be run as root. We now need to associate the file with a drive using the loop device tool losetup:

losetup /dev/loop0 ./drive.bin

Now we use cryptsetup, the front-end that provides all disc encryption capabilities on Linux through dm-crypt, to initialize the virtual volume we just made and set a key for it:

cryptsetup -s 256 -y luksFormat /dev/loop0

This will overwrite data on /dev/loop0 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter LUKS passphrase: [Enter password]
Verify passphrase: [Re-enter password]

Next, we use cryptsetup once again to "open" the volume and associate it to the device mapper, after the following command, the drive will show up in /dev/mapper/cryptvol:

cryptsetup luksOpen /dev/loop0 cryptvol
Enter passphrase for /dev/loop0: [Enter password]

The last step is to take your virtual drive you've just mapped and format it using your preferred filesystem, I use XFS here:

mkfs.xfs -f /dev/mapper/cryptvol

Now mount it, and use it as you would use a regular drive. The file /dev/mapper/cryptvol is seen by the system as an actual disk device. So you just have to run the following:

mkdir /media/cryptvol
mount /dev/mapper/cryptvol /media/cryptvol

That's it, now we have an XFS formatted virtual volume that's stored inside a file, associated as a loop device, and mapped through cryptsetup providing it with encryption. You can treat the folder /media/cryptvol just as you would a mounted drive. After you're done putting data or reading it, just do the following:

umount /media/cryptvol
cryptsetup luksClose cryptvol
losetup -d /dev/loop0

The first command unmount the userland level drive, the second command disassociates the mapper volume, and the last command removes the loop0 loop device from use.

The next time you want to mount the drive, just do the following:

losetup /dev/loop0 ./drive.bin
crypsetup luksOpen /dev/loop0 cryptvol
Enter passphrase for /dev/loop0: [Enter password]
mount /dev/mapper/cryptvol /media/cryptvol

And that's it, you now have a file that is encrypted with AES in cbc-essiv:sha256 mode that can be mounted as a volume. You can use a tool like hexedit to check that the data you put on the virtual volume is indeed encrypted.

Topic: Linux tags: linux, encryption