The internet is inherently insecure. Whenever you send data across it, there is a chance that that data could be sniffed, and someone could end up with your personal data. Hopefully once you've read this article, you'll have a better understanding of how to prevent this from happening.
When data travels through the internet, it needs to pass through multiple connections to get to its final destination. Most people don't realise that the data can be read by any machine it passes through on this journey.
With the right tools, you can sniff this data yourself, and any data that passes through your network. This is because most networks actually send data intended for anyone on that network to all machines on your network, and your computer will ignore anything that's not meant for it. This is especially true for most wireless networks, even networks that are 'secured' with WEP/WPA.
Ooh, what's that smell?
Let's try sniffing some of the data on your network. First of all, you need to install a tool called Wireshark. Most distributions have this available in their package manager, and for Ubuntu, I ran the command
sudo apt-get install wireshark
If your distribution doesn't provide this package, you can find the source code at www.wireshark.org/download.html, along with instructions on how to compile and install it.
In most instances, Wireshark needs to be run as the root user in your system. To run Wireshark, run the command gksu wireshark. You should be asked for your root password, after which Wireshark will load, giving you a brief warning that you are running it as root, and that it might be dangerous. You can generally ignore this for this tutorial, however, any program running as root might be dangerous, so be warned!
Wireshark requires root privileges to run, so make sure you're careful not to accidentally foul anything up.
When you run Wireshark, you'll be presented with a bare screen, with some icons at the top. For now we can ignore those items, as we need to capture some data first. In Wireshark, go to the Capture Menu and click on Interfaces. In this window, we select the interfaces on which we want to capture data. The simplest thing to do here is to use the 'Any' interface, which is Wireshark's way of saying "Collect any and all data that I can see on the network". Click on Start next to the Any interface, and you should see your main screen split into three, and the top portion of the window should start to fill up with data. If, like me, you're the only person on the network (or you have managed switches on your network), then you might not see much data appearing. Have a quick browse round on the internet, and you'll see more and more data appear (Wireshark captures any data coming and going from your computer, as well as other things on the network).
Wireshark lets you listen on any of your network connections.
To give an example of the kind of thing that can be sniffed, I ran through an installation of WordPress locally, and captured the data that was generated as I installed it.
As I know that WordPress works as a web page, and web pages use HTTP, I set Wireshark to only show HTTP packets. This is easily done by typing 'http' into the Filter box. You should now start to see some information in the Info column of the data. Let's look at how I logged in to WordPress.
When you submit a form on the web, you send data to the server using a method of HTTP called POST. Or, when you get a page, you use the HTTP method GET. To find where I've logged into the WordPress admin panel, I need to find the POST to the login script. Wireshark provides a lot of ways of manipulating the data, so let's search for all the POST requests that I've made.
Click on the Clear button next to the filter box, and then click on the Expression button. This window enables us to create an expression to filter the data. You can see from the Field Name list just how much Wireshark understands, but for now, we're just interested in finding POST requests, so scroll down to HTTP in that list, and expand it by clicking on the arrow next to it. Now we can select http.request.method below it, this says that we want to add a filter related to the request method that was used. Select http.request.method and in the Relation box, select == and type POST into the Value box, then click on OK.
I've now whittled my list down to only a few items, and I can see an item where I've posted to /wordpress/wp-login.php, so let's have a look at that in a bit more detail.
You should notice that the screen is now showing three sections (If it's not, try maximising the window). The central section of the window allows enables you drill down into the different bits of the packet. The bit that interests us here is the "Line-based text data" section, which shows one line, containing the following
This data is a URL encoded name value Pair String. Decoding it gives us the data shown in the table, below-left.
As you can see, this shows the username and password that you used to login to WordPress. This means that anyone sniffing your connection now has the username and password for your blog, and can do what they wish with it until you change your password.
Sniffed WordPress data
|Key ||Value |
|log ||admin |
|pwd ||HCnr9^@Wsbt |
|wp-submit ||Log In |
|redirect_to ||http://server/wordpress/wp-admin |
|testcookie ||1 |
Good Lord, that's scary!
What about your email? If you're using a normal email client, then you might find that you capture a conversation that looks something like this:-
< 220 stupor.sourceguru.net ESMTP Postfix (Ubuntu)
> EHLO sourceguru.net
> AUTH PLAIN JiM2NTUzMztseGZ1c2VyJiM2NTUzMztse
< 235 2.7.0 Authentication successful
> MAIL FROM:<firstname.lastname@example.org> SIZE=456 AUTH=<>
< 250 2.1.0 Ok
> RCPT TO:<email@example.com> ORCPT=rfc822;firstname.lastname@example.org
< 250 2.1.0 Ok
< 354 End data with <CR><LF>.<CR><LF>
> Date: Sun, 13 Sep 2009 20:59:06 +0100
> From: Martin Meredith <email@example.com>
> To: firstname.lastname@example.org
> Subject: Test Email
> Wireshark can sniff your email too
< 250 2.0.0 Ok: queued as 095CA94024
< 221 2.0.0 Bye
This is slightly scarier than the previous example. Imagine someone sitting outside your house with their laptop, listening on your Wi-Fi traffic. Not only can they read your email, but, from the innocuous line that starts AUTH PLAIN, they can find out your email account's username and password (which in this case, I've substituted for lxfuser/lxfpassword). The SMTP PLAIN authentication method simply combines your username and password, and base64 encodes them (which anyone can decode - just try it out at http://linkpot.net/scripture).
How do I stop people snooping?
All the above examples show how easy it is to obtain sensitive data from snooping on a connection. The best way to prevent this from happening is to encode the data that's being sent in a manner that an outsider cannot decode. This is called encryption. If you've ever shopped online, you've probably noticed the infamous green address bar in your browser (and to a lesser extent, the blue address bar), which is a visual sign that your browser is using an encrypted connection.
The most commonly used encryption methods on the internet are SSL (Secure Sockets Layer) and TLS (Transport Layer Security). Both work according to the notion of certificates and keys. The client (you) gets a certificate from the server and uses that to encrypt data to the server, which can only be decrypted using the server's private key. This private key can also encrypt data so that it can only be decrypted by the certificate. To make this more secure, when a secure connection is set up, a random key is generated, and this is used alongside the private key and certificate to encrypt the data between you and the server.
For you to be able to set up your own encrypted connections, you need to generate the SSL certificates. First of all you need to generate your private key. To do this, run the command:
openssl -genkey -out privey.pem 4096
This will generate your private key from the entropy on your system. Once you've created this, you need to generate a Certificate Signing Request (CSR). SSL Certificates are (usually) signed by a certification authority, which verifies who you are, and sign your certificate to confirm your identity. You can generate a CSR by running the following command:
openssl req -new -key privkey.pem -out cert.csr
You will be asked for some details when you do this. Fill them in, and make sure that the CommonName (CN) is set to the domain name for your server:
mez@lazy % openssl req -new -key privkey.pem -out cert.csr
Country Name (2 letter code) [AU]:UK
State or Province Name (full name) [Some-State]:West Midlands
Locality Name (eg, city) :Birmingham
Organization Name (eg, company) [Internet Widgits Pty Ltd]:.
Organizational Unit Name (eg, section) :.
Common Name (eg, YOUR name) :lazy.sourceguru.net
Email Address :email@example.com
You then need to send your CSR to your certification authority, who will send you back a signed certificate. We will save this as signed.pem. To make life easier, we'll combine the Key and Certificate into one file, so that we only have to set our configurations to point at that one file.
cat privkey.pem signed.pem > certificate.pem
We now have an SSL key and certificate we can use. Let's put them into practice.
Commonly, SSL certificates are signed by a certification authority to validate the identity of the person sending the certificate. If you've seen a green address bar in your browser, then the certificate that has been sent to you has had Extended Verification done on it. This means that you are able to tell that the server you are talking to belongs to the company that you are dealing with.
Most certification authorities charge to verify who you are, and in some cases, this can amount to thousands of pounds. An alternative for those without the amount of cash required for these commercial certificates is to use CAcert, an organisation that aims to provide free signed certificates for all its users. CAcert works on a Web of Trust (WoT) model to verify its users. To become a verified user of CAcert, you need to meet other users of CAcert and provide them with proof of identity. These users, if they are happy with the identification you have provided, will then give you 'points'. Once you get to 50 points, you can create 'assured' certificates, meaning that CAcert is confident in your identity. While CAcert is not recognised fully in all browsers by default, most Linux distros will ship with the needed files to allow CAcert-verified certificates to be treated just like a certificate generated by a commercial company would be.
The green address bar lets you know that your connection to a web server is encrypted.
Configuring your servers
The most common use of SSL is for secure websites, so it's convenient that Apache makes the process of setting up a secure server very simple. First of all, we need to create a 'site' within Apache. You can do this by creating a file containing the following in the /etc/apache2/sites-available directory (the path to our file will be /etc/apache2/sites-available/lazy.sourceguru.net):
After you've done this you need to enable the SSL module in Apache, enable the site you just created and restart Apache.
If you now visit your site, using a link like https://lazy.sourceguru.net you should see that your connection is now encrypted (it should have a blue or green address bar).
Email is a little more complicated, however, as in most cases, you will have one server to receive and another to send your email. For this example, I will be using Postfix and Courier, but if you have a different setup you'll find plenty of configuration guidance on the web.
Following the conversation
At times, the data that Wireshark presents can be overwhelming, especially if you're capturing data for a busy network (at your workplace, for example). To help you simplify things, Wireshark has the functionality to follow a TCP stream, allowing you to put together all the packets relevant to a single conversation between two machines. For example, imagine that you're looking through a capture, and find some packets related to someone chatting on IRC. You can follow the full conversation by right-clicking on the packet, and clicking on Follow TCP Stream.
Wireshark lets you follow a TCP conversation, for example, this chat with #ubuntu-uk conducted over IRC.
First of all, let's set up Postfix. If your mail setup requires you to use a different domain name than that one we've created a certificate for above, then you will need to create a new certificate. Once you've done this, Postfix is easy to configure. Add the following lines to your /etc/postfix/main.cf file:
smtpd_tls_cert_file = /path/to/certificate.pem
smtpd_tls_key_file = $smtpd_tls_cert_file
smtpd_tls_log_level = 0
smtpd_tls_recieved_header = yes
smtpd_tls_security_level = may
smtpd_use_tls = yes
smtpd_tls_auth_only = yes
Restart Postfix, and you should now be able to use TLS.
Courier is a service that provides POP and IMAP support. We'll show how to set up your POP server here, but the steps are almost exactly the same for the IMAP server.
Under Ubuntu, you firstly need to install the courier-pop-ssl package. Once you've done this, copy your certificate file to /etc/courier/pop3d.pem. Now, edit /etc/courier/pop3d and change the line:
This disables the normal POP3 interface's ability to start. However, as it's probably already running, we need to stop it, and restart the SSL version.
You now have a secured mail setup. Don't forget to change your client to use the new settings!
As we said at the start of the article, the internet is inherently insecure. The simplest and most effective way to combat this is to use encryption. We've shown you how to encrypt the traffic to and from your server, but it doesn't stop there. Almost any protocol on the internet can be snooped on, from your instant messenger to those interesting videos you watch at 3 am in the morning. So use encryption where you can - most server-based programs allow you to set it up simply and easily. If you're a programmer, and you're writing something new, remember your users, and give them an option to let them use your service securely.
Wireshark captures a huge amount of data, not all of which may be useful.
Randomness = better security
Many encryption methods use random data to help make the encryption more secure. On a lot of machines, (especially Linux desktops, VPSes and anything in the cloud) the amount of random data available to the system (called entropy) is used up very quickly. Linux generally gathers its entropy by measuring events such as minute differences in disk access times, so if your application isn't causing a lot of disk access, you may have insufficient available entropy to prevent someone from figuring out what random numbers are being generated.
Simtec Electronics has created a product that solves this problem: a small USB key that can be plugged into a system and uses quantum noise generators and then a lot of maths and cryptography to securely supply your system with random data at higher rate than your system can normally generate. You can find more details at www.entropykey.co.uk.
You should follow us on Identi.ca or Twitter