Nginx and Secure SSL Configuration

It turns out that it is kind of tricky to get a perfect high security SSL configuration. I will give you configuration options and I will explain the reasons for which they are chosen.

SSL Versions

SSLv2 is insecure and you also need to disable SSLv3, as TLS 1.0 suffers a downgrade attack, allowing an attacker to force a connection to use SSLv3 and therefore disable forward secrecy. SSLv3 also allows exploiting the POODLE attack which is another reason to disable it.

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;


The cipher suites that provide the best Forward Secrecy are the ones that use an ephemeral form of the Diffie-Hellman key exchange. The main disadvantage is their overhead which is improved by using their elliptic curve variants.

The following options are recommended by the Mozilla Foundation. If you are not looking for backwards compatibility the following is the recommended modern configuration that is compatible with: Firefox 27, Chrome 22, IE 11, Opera 14 and Safari 7.


For services that don't need compatibility with legacy clients (WinXP), but need to support a wide range of clients, the following less recommended configuration is compatible with: Firefox 1, Chrome 1, IE 7, Opera 5 and Safari 1.


And finally if for some crazy reason you would really like to support legacy systems like Windows XP and Internet Explorer 6, this is the NOT RECOMMENDED ciphersuite which will work with all clients back to Windows XP/IE6. It should only be used as a last resort.


Forward Secrecy and DHE Parameters

Forward Secrecy is a property of a secure communication that guarantees that even if an attacker gets a hold of the server's private key he would not be able to decrypt any past recorded communications. This is done by performing a Diffie-Hellman key exchange, which guarantees that the symmetric key of a communication (session key) is never transmitted over the connection and cannot be acquired from a third party. Because this key is only used for a limited amount of time it is called Ephemeral. The server's private key is then used to sign the negotiated session key and thus protecting from a MITM attack, which a standard Diffie-Hellman key exchange is vulnerable to. Nginx relies on an input parameters from OpenSSL for the Ephemeral Diffie-Hellman (DHE), but the OpenSSL defaults only provide a 1024-bit key for the key-exchange. Since often you will be using a 2048-bit certificate (or higher), DHE clients will use a weaker key-exchange than non-ephemeral DH clients. To set a stronger DHE parameter we generate an 4096-bit key and supply it to Nginx:

cd /etc/ssl/certs
openssl dhparam -out dhparam.pem 4096

And then in your Nginx configuration:

ssl_dhparam /etc/ssl/certs/dhparam.pem;

Additional Options

When choosing a cipher during an SSL or TLS handshake, normally the client's preference is used. If this directive is enabled, the server's preference will be used instead.

ssl_prefer_server_ciphers on;

SSL operations consume a lot of CPU resources. They can be optimised in the following way:

worker_processes auto;
http {
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;

    server { 
        keepalive_timeout   70;

An extra level of security can be achieved by enabling HTTP Strict Transport Security (HSTS). This is done by appending an extra header to each response signalling the browser that content from this domain should always be loaded via HTTPS.

server {
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Testing your SSL configuration

The SSL Labs have an excellent tool for testing you server configuration. I would highly recommend doing that after you've set up your server. If you get an A, then you are good to go!

Regular Expression Cheat Sheet

Every time I had to go to the lovely Rubular just to take a look at their Regex Quick Reference, I thought of composing a list of my own, a bit more detailed though. There are a dozen Regex hacks that I keep forgetting that are really useful and I have to look them up every time.

Well, hopefully with this list that won't have to happen again. And if you think of something that is missing, please leave a comment and I will add it.

Revision 4 (Each revision extends the article with new hacks. I'll bump the number whenever I add something new)

Skip and go to Hacks

Basic Regex Reference

Regex Description Regex Description Regex Description
[abc] A single character of: a, b, or c . Any single character (...) Capture everything enclosed
^ Start of line \s Any whitespace character (a|b) a or b
[^abc] Any single character except: a, b, or c \S Any non-whitespace character a? Zero or one of a
$ End of line \d Any digit a* Zero or more of a
[a-z] Any single character in the range a-z \D Any non-digit a+ One or more of a
\A Start of string \w Any word character (letter, number, underscore) a{3} Exactly 3 of a
[a-zA-Z] Any single character in the range a-z or A-Z \W Any non-word character a{3,} 3 or more of a
\z End of string \b Any word boundary a{3,6} Between 3 and 6 of a

Groups & Modifiers (Options)

Syntax Meaning
(foo) Capture everything enclosed
(?:foo) Group, but do not capture
(?=foo) Lookahead
(?<=foo) Lookbehind
(?!foo) Negative Lookahead
(?<!foo) Negative Lookbehind



Match everything until a sequence

Looking at the groups reference above, you can do that with a lookahead expression, like so:


This will match everything until the string foo.

To capture everything until foo, you can use the following:


Make sure you include the ? in the first capture group or otherwise that will result in an empty capture group at the end.

Capture everything until an optional sequence

Because Regex engines are greedy, what I showed above wont work with just adding an optional modifier to it (?). Instead you should do this:


This will capture both abc and abcfoo.

Greediness vs. Laziness

By default Regex is greedy. It would try to match as much as possible when you use operators like + or *. But sometimes you might only need to match more than one but as few as possible. This could be done by switching from Greedy mode to Lazy mode and is achieved by just adding a ? to the multiple operator like: +? or *?. This feature of Regex is called Possessive Quantifiers.

Here is a detailed example matching the string abbbbbc:

Now a bit more interesting

See how that reversed the order of the matches. Because greediness and laziness change the order in which permutations are tried, they can change the overall match. However, they do not change the fact that the regex engine will backtrack to try all possible permutations of the regular expression in case no match can be found. Possessive quantifiers are a way to prevent the regex engine from trying all permutations. This is useful for performance reasons. You can also use possessive quantifiers to eliminate certain matches.

P.S. This article could have been called: Harry Potter and the Power of Regex

Proxying Traffic through a DNS relay

There are cases in which the connection you have to the internet only allows DNS packets or traffic needs to be concealed. In those cases when an Internet connection is really required, one way to do that is through DNS relays.

How it works?

What essentially is going on is that instead of sending normal packets to the internet you are encoding your packets in DNS requests and sending those instead. You do need a special kind of DNS server that understands these modified DNS requests and responds appropriately. Of course owning a domain name is an absolute requirement for this and the shorter the domain is, the more space you have for channelling data. This is so because a full domain name cannot exceed 253 characters and thus your request cannot contain more that 253 - length(domain). There are some additional limitations to that, though.


Iodine is a very powerful utility that enables you to tunnel IPv4 data through a DNS server. Iodine runs on Linux, Mac OS X, FreeBSD, NetBSD, OpenBSD and Windows.

To try it out you will need to set up an iodined server. First you need to set up a domain name to use with iodine. It has to be as short as possible for example: Set up two DNS records. An A record pointing to your server and an NS record pointing to your A record, like this:

A             7200
NS  7200

Once you are ready you will need to set up the iodined (Iodine Daemon) on your server. This is done with the following command:

iodined -f -c -P secretpassword

Not that is the local address on which the server will appear when connecting through the tunnel.

Once you are ready it is simply a matter of running iodine and giving it your server domain name to create the tunnel:

iodine -f -P secretpassword

At this point of time you have a tunnel with DNS packets to your target server. This means that you will be able to access you server but nothing else. But if you want to use it as an Internet relay you could simply set up a proxy and use the tunnel for all kinds of data.

There are several methods to do this. You can either set up a VPN and route your traffic through the VPN or use an SSH proxy. Or even though not recommended, since your traffic won't be sent over a secure channel, but still worth mentioning are setting up an HTTP proxy on your server or setting up a route through your tunnel and configuring your server to do NAT.

After all the easiest (and secure) way to send your traffic over the tunnel is setting up an SSH proxy. This actually is pretty straight forward. All you need to do is run the following command and login to your server:

ssh user@ -D 1234

This will create a SOCKS proxy listening on localhost:1234 and you can configure either your computer to use it from the network settings or just your browser. There are plenty of tutorials on how to do that.

I definitely advise you to experiment with the -T, -L and -M arguments to establish the most efficient configuration and get lower latency and higher bandwidth. See the man page for details.

It does not provide a very high speed. Actually the speed of the connection can sometimes be really slow, depending on the network and the ping to your server, but iodine is a really powerful tool that can connect you to the internet even when there is no other way.


Hacktag iodined server

Now we give you the #hacktag iodined server available for free. You can connect to it with the following command:

iodine -f -P strongholdfreefallmonkey
ssh -n ihacktag@ -D 1234 # The password is the same

If you like it and/or use it often and you would like this service to stay online and be 99.9% available, please consider donating a small amount so we can get a proper server to host our iodined.

This entire article was created and uploaded using iodine.

How more secure could RSA be?

Breaking an RSA-10 key (meaning an RSA key 10 bits long), requires that you try every prime number in the range of 2 to 100. There are 25 of those, meaning that the security of RSA-10 is about equivalent to a 5-bit symmetric cipher. Doubling that, going to RSA-20 means that to crack it, you need to try every prime number in the range of 2 to 1000. There are 168 of those so the security of RSA-20 is equivalent to about an 8-bit symmetric cipher. Doubling the key length did not give us the security we naively expected. Each subsequent bit adds to the security of the key but always less than the preceding bit. Thus we quickly reach a point of diminishing returns after which every bit adds so little that it is almost negligible.

That point is reached around RSA-2048 and adding more bits to that doesn't make much difference. For comparison, RSA-2048 gives about 112 bits of security and RSA-3072 gives roughly 128 bits of security.

When someone someone asks you whether it is worth using RSA-4096, the only added security compared to RSA-2048 is about 28 bits, meaning a total of 140 bits.

If you need more security than what RSA-2048 offers, consider using Elliptic Curve cryptography rather than using RSA with an ever increasing key length.

So how more secure could RSA be? And the answer is: not much more secure.

Creative Commons

We truly believe that sharing, not only software but any kind of content/data in general, should be a human right. And from now all of the content on this website is provided under the terms of the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License unless otherwise stated.

Below is a brief description of what the license covers, but is not a substitute for the license.

This simply means that you are free to copy and redistribute the content of the website in any medium or format as long as you give as appropriate credit and provide a link to the license. You may not use any of the materials on the website for commercial purposes. You are free to remix, transform or build upon the material, but you man not distribute copies of the modified material.

This is done so we respect your right of sharing we believe in and you respect our right as copyright holders.

Content on the website and content we link to may be distributed under different license which will be explicitly stated.

Linux Cheat Sheet

This is a really useful list of bash one-liners for Linux and Unix so you can save those 5 minutes of time googling. This is for all the people who need a simple short snippet they can paste into bash, or fish for that matter, but might need some modifications.

I will add new snippets whenever I stumble upon something more interesting.

Revision 8 (Each revision extends the article with new commands. I'll bump the number whenever I add something new)


Generate a secure random password

There are many methods to perform this task. I am just going to mention my favourites.

This one uses the very useful dd command. On OS X you will need to lose the -w 0 from the base64 command.

dd if=/dev/urandom bs=1 count=33 2>/dev/null | base64

This uses openssl’s rand function, which may not be installed on your system. Good thing there are other examples, right?

openssl rand -base64 16
# To strip the equal signs at the end
openssl rand -base64 16 | head -c${1:-16}

Wait for internet connection

This will pause your script until there is network connection available. Really useful in some particular situations like boot time scripts, especially on machines relying on a WiFi connection.

for i in {1..50}; do ping -c1 &> /dev/null && break; done

List IP Addresses on all interfaces

This will list all IP Addresses of all interfaces connected to the system. You can use it in an espionage script to report it's current location on the internet.

ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1  -d’/'

Webserver from current directory

If for some reason you would like to start a webserver from the current directory downwards, here is a single line snippet thar does the job:

python -m SimpleHTTPServer 8080


Disable Root Password Login

usermod -p '!' root

Creating a Swap file

This creates a swap file located at /swapfile with the correct permissions and size specified in MB (The example demonstrates the creation of 512MB swap file).

dd if=/dev/zero of=/swapfile bs=1M count=512
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile   none    swap    sw    0   0' >> /etc/fstab

Increasing the space in /tmp

As with any other tmpfs, increasing the size of the /tmp with no data loss is just a matter of a simple remount.

mount -o remount,size=6G tmpfs /tmp

Creating a user

useradd -m -G wheel -s /bin/bash username

Some explanation:

Deleting a user

userdel user

You can add the -r option to remove the user's home directory and mail spool.

Adding an existing user to a group

usermod -a -G group user
gpasswd -a user group

Removing a user from a group

gpasswd -d user group
deluser user group

Checking process listening on a port

lsof -i :port
lsof -i tcp:port
lsof -i udp:port

Where port is the port number.


Generate a keypair

openssl genrsa -out private_key.pem 4096
openssl rsa -pubout -in private_key.pem -out public_key.pem

Generate a CSR

openssl req -key private_key.pem -new -out certificate_request.csr

Encrypt an RSA private key

openssl rsa -des3 -in private_key.pem -out encrypted_private_key.pem

The -des3 tells openssl to encrypt the key with DES3.

Remove the encryption from an RSA private key

openssl rsa -in -out server.key

Encrypt a file

Symmetric encryption

openssl aes-256-cbc -salt -in file.txt -out file.txt.enc

A few notes here: * You can use -a if you want your output to be in base64. This is useful if you would like to read it with a text editor or paste it in an email. * -salt makes the encryption stronger. You are advised to use it. * This uses symmetric encryption and you will be prompted for a password.

Asymmetric encryption

1. Generate a 256bit (32 byte) random key

  openssl rand -base64 32 > key.bin

2. Encrypt the key

openssl rsautl -encrypt -inkey public_key.pem -pubin -in key.bin -out key.bin.enc 

3. Encrypt the file

openssl enc -aes-256-cbc -salt -in file.txt -out file.txt.enc -pass file:./key.bin 

Note that you shouldn't encrypt the entire file with asymmetric encryption. That is too slow and inefficient. Instead you encrypt a 256bit key with which you encrypt the file. So when you are sending the encrypted file, you should send both the encrypted key and the encrypted file.
This procedure is slightly simpler when using PGP.

Decrypt a file

Symmetric encryption

openssl aes-256-cbc -d -in file.txt.enc -out file.txt

Again use -a if the input was encoded with base64.

Asymmetric encryption

1. Decrypt the key

openssl rsautl -decrypt -inkey private_key.pem -in key.bin.enc -out key.bin

2. Decrypt the file

openssl enc -d -aes-256-cbc -in file.txt.enc -out file.txt -pass file:./key.bin 


Changing your MAC address

While this is somewhat trivial, I would still like to mention it. Primarily because not many people are used to the new Linux ip utility.

You might need sudo for all of the commands.

Using ifconfig (Older Linux distros and Mac OS X)

ifconfig # to list all interfaces
ifconfig interface ether 00:00:00:00:DD

Using the new ip utility (Modern Linux distros like Arch)

ip link # To list interfaces and current configuration OR
ip link show interface # to list a specific interface.
ip link set dev interface address 00:00:00:00:DD

Note 1: You might have to turn of your interface before changing you address. This could be done with:

ifconfig interface up/down
ip link set dev interface up/down

Note 2: You have to substitute interface with your interface name. That is usually en* on Linux and OSX or wlan* for WiFi networks or the new wlp****.


Simple Port Scan

nmap -v host # -v is for verbosity
nmap -PN # Scans a host protected by a firewall
nmap -6 2607:f0d0:1002:51::4 # Scan an IPv6 host/address

Nmap Network Scan

Some of the arguments showed here could be used in the Port scan mode.

nmap -sP # Scan a network and find out which servers and devices are up and running
nmap -sA # Find out whether the host is protected by a Firewall
nmap 192.168.1.* -A # with OS and version detection
nmap --exclude # Excluding specific hosts

The Hacktag Project

Welcome to #hacktag!

We created this website in order to share the multiple projects we work on, our research, the interesting things we found out and the things we invented.

I hope you find it useful.

If for some reason you would like to ask us a question, feel free to go to the contacts section and leave us a message.

Kind Regards,
The Hacktag Team