NAT traversal

In a typical IPSec setup tunnels are established between equipment having public IPs. But what happen if one or both gateway are behind firewalls doing NAT ? As you can imagine this setup simply can’t work. There is two reasons for that.

First IKE exchange can’t be successful because of how NAT translations work. The embedded address of the source computer within the IP payload can’t match the source address of the IKE packet as it is replaced by the address of the NAT device.

Secondly ESP traffic can’t be NATed because there is no port in ESP. Therefore when a client attempts to initiate an ESP connection behind a network device doing NAT, the device is unable to maintain a unique translation state with these packets.

NAT-Traversal to the rescue !

To bypass these limitations, NAT-T was created. The idea is simply to a friendly NAT protocol (UDP) to encapsulate ESP exchange. During phase 1, if NAT-T is used, IKE negotiations switch to UDP port 4500.

After the tunnel is establish, instead of sending plain ESP packets, each one is encapsuled in an UDP packets. This trick allow the device doing NAT to maintain the connection state in its table.

Further Reading and sources

Initialize an encrypted external HDD or USB key

Prerequisites

  • an external hdd or usb key already partitioned
  • cryptsetup

Initializing

First format the partition:

cryptsetup luksFormat /dev/<partition>

Now we have a fresh new luks volume. Let’s open it:

cryptsetup luksOpen /dev/<partition> <my_alias>

The volume should be available under /dev/mapper/<my_alias>

Create a filesystem inside the volume:

mkfs.ext4 /dev/mapper/<my_alias>

Perfect. Now close the lurks volume:

cryptsetup luksClose <my_alias>

Initialization is done. Next time you will connect your device your file manager should prompt a pop-up asking the passphrase of your key.

Further Reading and sources

NSE scripts

The most powerful feature of nmap is its script engine. This allow you to use it in a semi-automatic mode, performing complex task, such as vulnerability detection, backdoor detection and even vulnerability exploitation.

You can find a list of NSE scripts here, and write your own in LUA.

Currently my two favorite are :

Introduction to fail2ban

While connecting to your server through SSH is secure, the SSH daemon itself is a service that must be exposed to the internet to function properly. Therefore it become a target for brute force attacks by bots. The good practice is always to filter access by IP, but what to do if you can’t ? Port-knocking and fail2ban will be my personal answer. Let talk about the latter.

What is fail2ban ?

fail2ban is a service that create iptable rules on-the-fly after a number of unsuccessful login attempts. This will allow your server to respond to illegitimate access attempts without intervention from you.

Configure fail2ban

The main setting file is /etc/fail2ban/jail.conf
The most important variables to adjust are maxretry which sets the number of tries a client can attempt and findtime which define the opportunity window and obviously bantime.

To specify which service fail2ban should check add a block like this:

[ssh]
enabled = true
port    = ssh,sftp
filter  = sshd
logpath  = /var/log/auth.log

If you wan to customize the regex pattern, you can look inside the /etc/fail2ban/filter.d directory. Don’t forget to reload the daemon and test your configuration.

Further Reading and sources

[Apache] CORS header

What is CORS ?

CORS or cross-origin resource sharing is a mechanism that allows resources on a web page to be requested from a different domain than the page origin. To do that the CORS mecanism use a specific header: Access-Control-Allow-Origin.

For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. For example XMLHttpRequest and Fetch follow the same-origin policy. This header allow you to customize this behavior.

Authorize a domain

Just add to your apache configuration:

Header set Access-Control-Allow-Origin "https://www.domain.com"

Authorize multiple domains

Access-Control-Allow-Origin can take only one value. You could use the value * but that ugly and defeat the whole purpose of filtering request domain origin.

But with a little trickery you can do that:

SetEnvIfNoCase Origin "https?://(domain\.com|staging\.domain\.com)(:\d+)?$" ACAO=$0
Header set Access-Control-Allow-Origin %{ACAO}e env=ACAO

This regex use the content of the Origin header and define a matching Access-Control-Allow-Origin value. Here we authorize both the http and https versions of domain.com and staging.domain.com to load ressources from our domain.

Further Reading and sources

The heartbleed vulnerability

What is heartbleed ?

Heartbleed is the name given to a critical vulnerability in the OpenSSL library. The official designation of this bug is CVE-2014-0160. Theoretically this vulnerability could be use by an attacker to gain access to data transmitted between clients and server, by random chunk of 64ko. Retrieved content could be pretty much anything: session content, password, even the server private key.

How did this happen ?

The vulnerability is due to a missing validation on a variable size. The bug was introduced into OpenSSL 1.0.1 and fixed into version 1.0.1g.

How does it work ?

The following XKCD comic does a pretty good job at explaining the issue in simple terms.

To test if your server is vulnerable

Use this: https://filippo.io/Heartbleed

What to do ?

First don’t panic and make security updates. Check you have an OpenSSL version 1.0.1g or higher. Because of the buzz around the vulnerability most SSL providers offer free certificate regeneration. Jump on the offer, regenerate your server private key and CSR.

Further Reading and sources

Verify a SSL certificate installation with openssl

Usually people use their browser or a dedicated website like ssltest to test a server certificate installation.

But you can do it directly with the openssl command:

# openssl s_client -CApath /etc/ssl/certs/ -connect www.foobar.com:443
...
...
New, TLSv1/SSLv3, Cipher is AES256-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : AES256-SHA256
    Session-ID: 9E01CD86FA9F1483AD505F17E34C0B9BF99F57BBF9B5E6A5F2946F8858A86807
    Session-ID-ctx: 
    Master-Key: 8ED5443DCD5F6706A0DF5C0196E1B3AFBAAD3FB0B5B680EB212D4FC3F2BCC24209D0E241FBA746D85559CFA8539D99F4
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1474905181
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

The line Verify return code: 0 indicate a correct installation. Note that the -CApath option tells openssl where to look for the CA certificates. On Debian the directory is /etc/ssl/certs/.

nmap

nmap aka. network mapper is a very versatile network tool. It can be use to explore networks, perform quick ‘security’ audit and find open ports on remote machines.

Scan an IP

# nmap 192.168.0.4

Scan a range

# nmap 192.168.0.4-22

Scan a subnet

# nmap 192.168.0.0/24

Beside providing a netmask you can also use a wildcard character:

# nmap 192.168.0.*

Exclude an IP from a scan

Use the --exclude option. You can specify an IP or a range.

Scan a list of hosts from a file

Use the -iL option. nmap will use the file content as a list of host to scan.

Find out ‘live’ hosts in a network

Use the -sP option. Only the responsive hosts will be listed:

# nmap -sP 10.4.0.0/24

Guess the host OS

Use the -O --osscan-guess options. nmap will try to determine the OS of the scanned hosts using several tricks.

Perform a tcp null scan to “fool” a firewall

# nmap -sN 192.168.0.4

Configure SFTP access with ProFTPd

Since version 1.3.3rc1 ProFTPd have a mod_sftp module. This module implements the core functionalities of the SSH2 protocol and its SFTP subsystem.

Using ProFTPd implementation brings some practical advantages:

  • no need to spawn another OpenSSH daemon on a another port
  • no need to tweak sshd_config to allow chrooted SFTP
  • you can chroot a user into any directory even ones which doesn’t belong to root
  • you can use ‘virtual’ accounts instead of unix ones

Enable SFTP support

Add the following block to /etc/proftpd/proftpd.conf:

SFTPEngine on

Port 115
SFTPLog /var/log/proftpd/sftp.log
TransferLog /var/log/proftpd/sftp-xferlog

# Host Keys
SFTPHostKey /etc/ssh/ssh_host_rsa_key
SFTPHostKey /etc/ssh/ssh_host_dsa_key

# SFTP specific configuration
DefaultRoot ~

I arbitrary chose the port TCP 115 because that the port for SFTP after all (just not the same SFTP) 😉

Choose the authentication method

Like OpenSSH it can be done by password or by public key. For password add the following snippet to /etc/proftpd/proftpd.conf:

# Authentication method
SFTPAuthMethods password
AuthUserFile /etc/proftpd/sftp.passwd

If you prefer using keys:

# Authentication method
SFTPAuthMethods publickey
SFTPAuthorizedUserKeys file:/etc/proftpd/sftp.passwd.keys/%u

Create users accounts

We will use ProFTPd virtual account system. First we create the account file:

touch /etc/proftpd/sftp.passwd
chown proftpd /etc/proftpd/sftp.passwd
chmod go-rwx /etc/proftpd/sftp.passwd

File syntax is very simple:

username:PASSWORD_HASH:UID:GID:Comment for human:/home/user_home:/bin/bash

To generate the password you can use pwgen and hash it with md5 like this:

PASS=$(pwgen -Bs1 15); echo $PASS
mkpasswd --hash=md5 $PASS

UID and GID must be numerical values. You can use value from an actual unix account to map the virtual user to it.

Add user public keys

If you prefer using keys authentication, create a dedicated directory for storing keys:

mkdir /etc/proftpd/sftp.passwd.keys
chown proftpd /etc/proftpd/sftp.passwd.keys
chmod go-rwx /etc/proftpd/sftp.passwd.keys

Then create a file per SFTP user and fill it with the public keys you want. Don’t forget to convert them into RFC4716 format before:

ssh-keygen -e -f key_to_convert.pub > key_in_rfc4716.pub

After all theses modifications, restart ProFTPd and test. Adjust firewall rules accordingly.

Further Reading and sources