I recently moved to Linux and have all my hard drives Luks encrypted, including the primary. I decided to convert my ext4 partitions to Btrfs recently, which I’m totally loving. I also decided to grab another nvme drive and use it as a RAID1 (mirror) drive against my primary drive, using Btrfs’ RAID mechanics. Below are the instructions to accomplish this.
Do note that this is for a situation where you already have a BTRFS volume and want to add a device as RAID1. This assumes you already have your system booting to the LUKS encrypted drive with the root being btrfs. Many modern Linux OS installers can do this for you automatically. Parts of these instructions can still be used in other situations.
Hopefully you also have a swap partition under the same LVM as your LUKS root (the Linux Mint installer does this by default), as we’ll be using it. If not, you’ll need to modify the instructions. This script resizes the swap partition and adds an “extra” partition to hold your drive key. This is required because a drive key cannot be loaded off your btrfs volume as both drives need to be unlocked first.
This should be ran from another operating system. I would recommend using Universal USB Installer to do this. It allows you to put multiple OS live cds on a USB key, including optional persistence.
Run the following script as root (you can use sudo). Make sure to fill in the variables section first. Or even better, run the script 1 line at a time to make sure there are no problems.
#!/bin/bash
#-----------------------------------Variables----------------------------------
#Current root drive
CurPart="nvme0n1p3" #The current drive partition in /dev. This example uses nvme disk #0 partition #3
CurCryptVol="vgmint" #What you named your LVM under LUKS
CurCryptRoot="root" #What you named your root partition under the LVM
CurCryptRootSubVol="/" #The path of the subvolume that is used as the root partition. For example, I use “@”
CurCryptSwap="swap_1" #What you named your swap partition under the LVM
CurCryptExtra="extra" #What you WANT to name your extra partition under the LVM
CurCryptExtraSize="100M" #How big you want your extra partition that will hold your key file
CurKeyPath="" #The path to a key file that will unlock both drives. If left blank then one will be created
#New drive
NewDrive="nvme1n1" #The new drive in /dev. This example uses nvme disk #1
NewPart="nvme1n1p3" #The new partition in /dev. You will be creating this with the cfdisk. This example uses nvme disk#1 partition#3
NewCryptName="raid1_crypt" #What we’ll name the root LUKS partition (no LVM)
#Other variables you do not need to set
CurMount="/mnt/primary"
ExtraMountPath="$CurMount/mnt/extra"
BtrfsReleasePath="kdave/btrfs-progs"
BtrfsReleaseFile="btrfs.box.static"
DriveKeyName="drivekey"
echo "---------------------------------Update BTRFS---------------------------------"
echo "Make sure you are using the latest btrfs-progs"
cd "$(dirname "$(which btrfs)")"
LATEST_RELEASE=$(curl -s "https://api.github.com/repos/$BtrfsReleasePath/releases/latest" | grep tag_name | cut -d \" -f4)
wget "https://github.com/$BtrfsReleasePath/releases/download/$LATEST_RELEASE/$BtrfsReleaseFile"
chmod +x "$BtrfsReleaseFile"
echo "Link all btrfs programs to btrfs.box.static. Rename old files as .old.FILENAME"
if ! [ -L ./btrfs ]; then
for v in $(\ls btrfs*); do
if [ "$v" != "$BtrfsReleaseFile" ]; then
mv "$v" ".old.$v"
ln -s "$BtrfsReleaseFile" "$v"
fi
done
fi
echo "--------------------------Current drive and key setup-------------------------"
echo "Mount the current root partition"
cryptsetup luksOpen "/dev/$CurPart" "$CurCryptVol"
vgchange -ay "$CurCryptVol"
mkdir -p "$CurMount"
mount -o "subvol=$CurCryptRootSubVol" "/dev/$CurCryptVol/$CurCryptRoot" "$CurMount"
echo "If the extra volume has not been created, then resize the swap and create it"
if ! [ -e "/dev/$CurCryptVol/$CurCryptExtra" ]; then
lvremove -y "/dev/$CurCryptVol/$CurCryptSwap"
lvcreate -n "$CurCryptExtra" -L "$CurCryptExtraSize" "$CurCryptVol"
mkfs.ext4 "/dev/$CurCryptVol/$CurCryptExtra"
lvcreate -n "$CurCryptSwap" -l 100%FREE "$CurCryptVol"
mkswap "/dev/$CurCryptVol/$CurCryptSwap"
fi
echo "Make sure the key file exists, if it does not, either copy it (if given in $CurKeyPath) or create it"
mkdir -p "$ExtraMountPath"
mount "/dev/$CurCryptVol/$CurCryptExtra" "$ExtraMountPath"
if ! [ -e "$ExtraMountPath/$DriveKeyName" ]; then
if [ "$CurKeyPath" != "" ]; then
if ! [ -e "$CurKeyPath" ]; then
echo "Not found: $CurKeyPath"
exit 1
fi
cp "$CurKeyPath" "$ExtraMountPath/$DriveKeyName"
else
openssl rand -out "$ExtraMountPath/$DriveKeyName" 512
fi
chmod 400 "$ExtraMountPath/$DriveKeyName"
chown root:root "$ExtraMountPath/$DriveKeyName"
fi
echo "Make sure the key file works on the current drive"
if cryptsetup --test-passphrase luksOpen --key-file "$ExtraMountPath/$DriveKeyName" "/dev/$CurPart" test; then
echo "Keyfile successfully opened the LUKS partition."
#cryptsetup luksClose test #This doesn’t seem to be needed
else
echo "Adding keyfile to the LUKS partition"
cryptsetup luksAddKey "/dev/$CurPart" "$ExtraMountPath/$DriveKeyName"
fi
echo "--------------------------------New drive setup-------------------------------"
echo "Use cfdisk to set the new disk as GPT and add partitions."
echo "Make sure to mark the partition you want to use for the raid disk as type “Linux Filesystem”."
echo "Also make it the same size as /dev/$CurPart to avoid errors"
cfdisk "/dev/$NewDrive"
echo "Encrypt the new partition"
cryptsetup luksFormat "/dev/$NewPart"
echo "Open the encrypted partition"
cryptsetup luksOpen "/dev/$NewPart" "$NewCryptName"
echo "Add the key to the partition"
cryptsetup luksAddKey "/dev/$NewPart" "$ExtraMountPath/$DriveKeyName"
echo "Add the new partition to the root btrfs file system"
btrfs device add "/dev/mapper/$NewCryptName" "$CurMount"
echo "Convert to RAID1"
btrfs balance start -dconvert=raid1 -mconvert=raid1 "$CurMount"
echo "Confirm both disks are in use"
btrfs filesystem usage "$CurMount"
echo "--------------------Booting script to load encrypted drives-------------------"
echo "Get the UUID of the second btrfs volume"
Drive2_UUID=$(lsblk -o UUID -d "/dev/$NewPart" | tail -n1)
echo "Create a script to open your second luks volumes before mounting the partition"
echo "Note: In some scenarios this may need to go into “scripts/local-premount” instead of “scripts/local-bottom”"
cat <<EOF > "$CurMount/etc/initramfs-tools/scripts/local-bottom/unlock_drive2"
#!/bin/sh
PREREQ=""
prereqs()
{
echo "\$PREREQ"
}
case "\$1" in
prereqs)
prereqs
exit 0
;;
esac
. /scripts/functions
cryptroot-unlock
vgchange -ay "$CurCryptVol"
mkdir -p /mnt/keyfile
mount "/dev/$CurCryptVol/$CurCryptExtra" /mnt/keyfile
cryptsetup luksOpen /dev/disk/by-uuid/$Drive2_UUID "$NewCryptName" "--key-file=/mnt/keyfile/$DriveKeyName"
umount /mnt/keyfile
rmdir /mnt/keyfile
mount -t btrfs -o "subvol=$CurCryptRootSubVol" "/dev/$CurCryptVol/$CurCryptRoot" /root
#If you are weird like me and /usr is stored elsewhere, here is where you would need to mount it.
#It cannot be done through your fstab in this setup.
#mount --bind /root/sub/sys/usr /root/usr
mount --bind /dev /root/dev
mount --bind /proc /root/proc
mount --bind /sys /root/sys
EOF
chmod 755 "$CurMount/etc/initramfs-tools/scripts/local-bottom/unlock_drive2"
echo "--------------------Setup booting from the root file system-------------------"
echo "Prepare a chroot environment"
for i in dev dev/pts proc sys run tmp; do
mount -o bind /$i "$CurMount/$i"
done
echo "Run commands in the chroot environment to update initramfs and grub"
chroot "$CurMount" <<EOF
echo "Mount the other partitions (specifically for “boot” and “boot/efi”)"
mount -a
echo "Update initramfs and grub"
update-initramfs -u -k all
update-grub
EOF
echo "-----------------------------------Finish up----------------------------------"
echo "Reboot and pray"
reboot
The following is a tutorial on mounting a dd image of a TrueCrypt system-level-encrypted volume. This tutorial was tested and written against Ubuntu 16.04.2 LTS.
Trying to mount your loopback device with losetup or mount doesn’t quite work. If you tried, you’d get an error like the following:
No such file or directory:
/sys/block/loop2/loop2p2/start
VeraCrypt::File::Open:276
Instead, use sudo kpartx -va IMAGE_FILENAME.
This will give you something like the following:
add map loop2p1 (253:0): 0 204800 linear 7:2 2048
add map loop2p2 (253:1): 0 976564224 linear 7:2 206848
This shows you the partitions in the image and which loopback devices they are mounted to. In my case, loop2 and loop2p2, which I will continue using for the rest of this tutorial.
So this mounts the following:
/dev/loop2: The primary loopback device
/dev/mapper/loop2p*: The partition loopback devices (in my case, loop2p1 and loop2p2)
If you attempt to mount loop2p2 with TrueCrypt or VeraCrypt as a system partition, no matter the password, you will get the error “Partition device required”.
To fix this we need to get the loop2p2 to show up in /dev and make an edit to the VeraCrypt source code.
You can run the following command to see the loopback partition devices and their sizes. This is where I am pulling loop2p2 from.
lsblk /dev/loop2
This will give the following:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop2 7:2 0 465.8G 1 loop
├─loop2p2 253:1 0 465.7G 1 part
└─loop2p1 253:0 0 100M 1 part
Run the following command to create /dev/loop2p* block devices:
sudo partx -a /dev/loop2
Run the following commands to download and compile VeraCrypt:
sudo apt-get install git yasm libfuse-dev libwxgtk3.0-dev #yasm requires universe repository
git clone https://github.com/veracrypt/VeraCrypt
cd VeraCrypt/src
nano Platform/Unix/FilesystemPath.cpp#You can use the editor of your choice for this
In Platform/Unix/FilesystemPath.cpp make the following change:
After the following 2 lines of code in the FilesystemPath::ToHostDriveOfPartition() function, currently Line 78:
Then continue to run the following commands to finish up:
make
Main/veracrypt -m system,ro,nokernelcrypto -tc /dev/loop2p2YOUR_MOUNT_LOCATION
VeraCrypt parameter information:
If you don’t include the “nokernelcrypto” option, you will get the following error:
device-mapper: reload ioctl on veracrypt1 failed: Device or resource busy
Command failed
the “ro” is if you want to mount in readonly
“-tc” means the volume was created in TrueCrypt (not VeraCrypt)
Doing this in Windows is a lot easier. You just need to use a program called Arsenal Image Mounter to mount the drive, and then mount the partition in TrueCrypt (or VeraCrypt).
I’ve always thought that the RSA and Diffie–Hellman public key encryption algorithm systems are beautiful in their complex simplicity. While there are countless articles out there explaining how to implement them, I have never really found one that I think describes the math behind then in a simple way, so I thought I’d give a crack at it.
Both algorithms are derived from 3 math axioms:
This is called Modular exponentiation (hereby referred to as modexp). In the following, x is a prime numbers and p is an integer less than x.
A further derivation from the above formulas shows that we can combine primes and they work in the same manner. In the following, x and y are prime numbers and p is an integer less than x*y.
Note: This formula is not used in RSA but it helps demonstrate how the formulas from part 1 becomes formula 2b.
Due to how modexp works with primes, values of p that are multiples of x or y do not work with 2a.
The final axiom is how modexp can be split apart the same way as in algebra where (x^a)^b === x^(a*b). For any integers p, x, y, and m:
(p^(x*y) mod m) === ((p^x mod m)^y mod m)
With these 3 axioms we have everything we need to explain how RSA works. To execute an RSA exchange, encrypted from Bob and decrypted by Alice, the following things are needed.
The variable
Variable name
Who has it
Who uses it
Description
Prime Numbers 1 and 2
Prime1, Prime2
Alice
Alice
Alice will use these to derive variables PubKey, PrivKey, and Modulo. In our examples we use small numbers, but in reality, very large primes will be used, generally of at least 256 bit size.
Public key
PubKey
Alice, Bob
Bob
Alice sends this to Bob so he can encrypt data to her. Bob uses it as an exponent in a modexp.
Private key
PrivKey
Alice
Alice
Alice uses this to decrypt what Bob sends her. Alice uses it as an exponent in a modexp.
Modulo
Modulo
Bob, Alice
Bob, Alice
Alice sends this to Bob. They both use it as a modulo in a modexp
Payload Data
Payload
The data bob starts with and turns into EncryptedPayload. Alice derives Payload back from EncryptedPayload
Now, let’s start with axiom 2b:
Payload^((Prime1-1)*(Prime2-1)+1) mod (Prime1*Prime2) = Payload
Let’s change this up so the exponent is just 2 multiplications so we can use axiom 3 on it. We need to find 2 integers to become PubKey and PrivKey such that:
PubKey*PrivKey=(Prime1-1)*(Prime2-1)+1
And Modulo is Prime1*Prime2.
So we now have:
Payload^(PubKey*PrivKey) mod Modulo = Payload
Now, using axiom 3, we can turn it into this:
(Payload^PubKey mod Modulo)^PrivKey mod Modulo = Payload
Now, we can split this up into:
Bob calculates and sends to Alice: Payload^PubKey mod Modulo=EncryptedPayload
Alice uses the received EncryptedPayload and performs: EncryptedPayload^PrivKey mod Modulo = Payload
And the process is complete!
However, there is 1 caveat that I didn’t cover which makes the encryption that what we currently have weak. The calculation of PubKey and PrivKey from Prime1 and Prime2 needs to follow some rather specific complex rules to make the keys strong. Without this, an attacker may be able to figure out Prime1 and Prime2 from the Modulo and PubKey, and could then easily derive PrivKey from it. I generally see the PubKey as 65535, or another power of 2 minus 1.
After a little over a year of waiting, Let’s Encrypt has finally opened its doors to the public! Let’s Encrypt is a free https certificate authority, with the goal of getting the entire web off of http (unencrypted) and on to https. I consider this a very important undertaking, as encryption is one of the best ways we can fight illegal government surveillance. The more out there that is encrypted, the harder it will be to spy on people.
I went ahead and got it up and running on 2 servers today, which was a bit of a pain in the butt. It [no longer] supports Python 2.6, and was also very unhappy with my CentOS 6.4 cPanel install. Also, when you first run the letsencrypt-auto executable script as instructed by the site, it opens up your package manager and immediately starts downloading LOTS of packages. I found this to be quite anti-social, especially as I had not yet seen anywhere, or been warned, that it would do this before I started the install, but oh well. It is convenient. The problem in cPanel was that a specific library, libffi, was causing problems during the install.
To fix the Python problem for all of my servers, I had to install Python 2.7 as an alt Python install so it wouldn’t mess with any existing infrastructure using Python 2.6. After that, I also set the current alias of “python” to “python2.7” so the local shell would pick up on the correct version of Python.
As root in a clean directory:
wget https://www.python.org/ftp/python/2.7.8/Python-2.7.8.tgz
tar -xzvf Python-2.7.8.tgz
cd Python-2.7.8
./configure --prefix=/usr/local
make
make altinstall
alias python=python2.7
The cPanel lib problem was caused by libffi already being installed as 3.0.9-1.el5.rf, but yum wanted to install its devel package as version 3.0.5-3.2.el6.x86_64 (an older version). It did not like running conflicting versions. All that was needed to fix the problem was to manually download and install the same devel version as the current live version.
Unfortunately, the apache plugin was also not working, so I had to do a manual install with “certonly” and “--webroot”.
And that was it; letsencrypt was ready to go and start signing my domains! You can check out my current certificate, issued today, that currently has 13 domains tied to it!
I wanted to play around with Google's go language a little so I ended up decided on making a simple class that helps create a TCP connection between a server and client that is encrypted via TLS, or not, depending upon a flag. Having the ability to not encrypt a connection is useful for debugging and testing purposes, especially if other people are needing to create clients to connect to your server.
The example server.go file listens on port 16001 and for every set of data it receives, it sends the reversed string back to the client. (Note there are limitations to the string lengths in the examples due to buffer and packet payload length restrictions).
The example client.go file connects to the server (given via the 1st command line parameter), optionally encrypts the connection (depending upon the 2nd command line parameter), and sends the rest of the parameters to the server as strings.
The encryptedtcp.go class has the following exported functions:
StartServer: Goes into a connection accepting loop. Whenever a connection is accepted, it checks the data stream for either the "ENCR" or "PTXT" flags, which control whether a TLS connection is created or not. The passed "clientHandler" function is called once the connection is completed.
StartClient: Connects to a server, passes either the "ENCR" or "PTXT" flag as noted above, and returns the finished connection.
Connections are returned as "ReadWriteClose" interfaces. Creating the pem and key certificate files is done via openssl. You can just google for examples.
server.go:
package main
import ( "./encryptedtcp"; "fmt"; "log" )
func main() {
if err := encryptedtcp.StartServer("server.pem", "server.key", "0.0.0.0:16001", handleClient); err != nil {
log.Printf("%q\n", err) }
}
func handleClient(conn encryptedtcp.ReadWriteClose) {
buf := make([]byte, 512)
for {
//Read data
n, err := conn.Read(buf)
if err != nil {
log.Printf("Error Reading: %q\n", err); break }
fmt.Printf("Received: %q\n", string(buf[:n]))
//Reverse data
for i, m := 0, n/2; i<m; i++ { //Iterate over half the list
buf[i], buf[n-i-1] = buf[n-i-1], buf[i] } //Swap first and half of list 1 char at a time
//Echo back reversed data
n, err = conn.Write(buf[:n])
if err != nil {
log.Printf("Error Writing: %q\n", err); break }
fmt.Printf("Sent: %q\n", string(buf[:n]))
}
}
client.go:
package main
import ( "./encryptedtcp"; "fmt"; "log"; "os" )
func main() {
//Confirm parameters, and if invalid, print the help
if len(os.Args) < 4 || (os.Args[2] != "y" && os.Args[2] != "n") {
log.Print("First Parameter: ip address to connect to\nSecond Parameter: y = encrypted, n = unencrypted\nAdditional Parameters (at least 1 required): messages to send\n"); return }
//Initialize the connection
conn, err := encryptedtcp.StartClient("client.pem", "client.key", os.Args[1]+":16001", os.Args[2]=="y" )
if err != nil {
log.Printf("%q\n", err); return }
defer conn.Close()
//Process all parameters past the first
buf := make([]byte, 512)
for _, msg := range os.Args[3:] {
//Send the parameter
if(len(msg)==0) {
continue }
n, err := conn.Write([]byte(msg))
if err != nil {
log.Printf("Error Writing: %q\n", err); break }
fmt.Printf("Sent: %q\n", msg[:n])
//Receive the reply
n, err = conn.Read(buf)
if err != nil {
log.Printf("Error Reading: %q\n", err); break }
fmt.Printf("Received: %q\n", string(buf[:n]))
}
}
encryptedtcp/encryptedtcp.go:
//A simple TCP client/server that can be encrypted (via tls) or not, depending on a flag passed from the client
package encryptedtcp
import ( "crypto/rand"; "crypto/tls"; "net"; "log" )
//Goes into a loop to accept clients. Returns a string on error
func StartServer(certFile, keyFile, listenOn string, clientHandler func(ReadWriteClose)) (error) {
//Configure the certificate information
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return MyError{"Cannot Load Keys", err} }
conf := tls.Config{Certificates:[]tls.Certificate{cert}, ClientAuth:tls.RequireAnyClientCert, Rand:rand.Reader}
//Create the listener
listener, err := net.Listen("tcp", listenOn)
if err != nil {
return MyError{"Cannot Listen", err} }
defer listener.Close()
//Listen and dispatch clients
for {
conn, err := listener.Accept()
if err != nil {
return MyError{"Cannot Accept Client", err} }
go startHandleClient(conn, &conf, clientHandler)
}
//No error to return - This state is unreachable in the current library
return nil
}
//Return the io stream for the connected client
func startHandleClient(conn net.Conn, conf* tls.Config, clientHandler func(ReadWriteClose)) {
defer conn.Close()
//Confirm encrypted connection flag (ENCR = yes, PTXT = no)
isEncrypted := make([]byte, 4)
amountRead, err := conn.Read(isEncrypted)
if err != nil {
log.Printf("Cannot get Encrypted Flag: %q\n", err); return }
if amountRead != 4 {
log.Printf("Cannot get Encrypted Flag: %q\n", "Invalid flag length"); return }
if string(isEncrypted) == "PTXT" { //If plain text, just pass the net.Conn object to the client handler
clientHandler(conn); return
} else if string(isEncrypted) != "ENCR" { //If not a valid flag value
log.Printf("Invalid flag value: %q\n", isEncrypted); return }
//Initialize the tls session
tlsconn := tls.Server(conn, conf)
defer tlsconn.Close()
if err := tlsconn.Handshake(); err != nil {
log.Printf("TLS handshake failed: %q\n", err); return }
//Pass the tls.Conn object to the client handler
clientHandler(tlsconn)
}
//Start a client connection
func StartClient(certFile, keyFile, connectTo string, isEncrypted bool) (ReadWriteClose, error) {
//Configure the certificate information
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return nil, MyError{"Cannot Load Keys", err} }
conf := tls.Config{Certificates:[]tls.Certificate{cert}, InsecureSkipVerify:true}
//Connect to the server
tcpconn, err := net.Dial("tcp", connectTo)
if err != nil {
return nil, MyError{"Cannot Connect", err} }
//Handle unencrypted connections
if !isEncrypted {
tcpconn.Write([]byte("PTXT"))
return tcpconn, nil //Return the base tcp connection
}
//Initialize encrypted connections
tcpconn.Write([]byte("ENCR"))
conn := tls.Client(tcpconn, &conf)
conn.Handshake()
//Confirm handshake was successful
state := conn.ConnectionState()
if !state.HandshakeComplete || !state.NegotiatedProtocolIsMutual {
conn.Close()
if !state.HandshakeComplete {
return nil, MyError{"Handshake did not complete successfully", nil}
} else {
return nil, MyError{"Negotiated Protocol Is Not Mutual", nil} }
}
//Return the tls connection
return conn, nil
}
//Error handling
type MyError struct {
Context string
TheError error
}
func (e MyError) Error() string {
return e.Context+": "+e.TheError.Error(); }
//Interface for socket objects (read, write, close)
type ReadWriteClose interface {
Read(b []byte) (n int, err error)
Write(b []byte) (n int, err error)
Close() error
}
A friend of mine recently asked me about the TOR network because of a PC world article he had read. First, I’d like to state that the article actually has a lot of good general information, covering a lot of general security problems with solutions to them that have been time proven and useful to millions of people (VPNs, privacy/incognito mode in browsers, cookie management, bugmenot, etc). However, I think the article does not cover the realities of TOR and VPNs at all, so I figured I’d write up an article on these topics that I could share with my inquisitive friend and anyone else who is interested.
I used TOR back in the early 2000s and it’s not cracked up to what the article would have you think. Basically, it securely routes your connection through a few other people’s internet connections (we’ll say 3 for examples sake). The computers/nodes between you and the “exit node” in the route can’t read what your traffic data says because it’s all encrypted, but the final person/computer (the “exit node”) literally sees, in clear text, 100% of your data as if you were sending/receiving it out of your own machine without the TOR network. So if you are doing anything that isn’t natively encrypted (instant message chatting without OTR, going to a site via http instead of https) the exit node can snoop on everything you do. They can even see the domain (not the entire URL) of WHERE you are going with https1. If I recall, you can’t really control the exit node as, I think, it semi-randomly picks it from any person in the world running a TOR router node.
So all TOR really does for you is make servers that you connect to not know from where you are coming. So one day it may think you are coming from Michigan, and another day, from Singapore. And honestly, for most people that isn’t even really all that important. Do you really care if servers you go to on the internet know you are coming in from your home town? (They generally can’t pinpoint further than that without getting a warrant and asking the ISP). All that's really done with this data is correlation. Seeing that someone from this IP address that went to this one website also went to this other website.
And even worse, TOR is known for being ungodly slow. Back when I was using it I was LUCKY to get 15KB/s throughput on my connections, and I doubt it has changed much (though you could get lucky too on your “randomly” chosen connection nodes). This means to download a normal webpage (~1.5MB for arguments sake) it would take ~2 minutes to download the page instead of 1-2 seconds for normal broadband users.
The more important thing (than anonymity) for online security is making sure everything you do is encrypted end point to end point (privacy). That means using securely encrypted (usually SSL) connections (https is SSL on top of http). That makes it so no one can snoop on conversations between your computer and the server you are communicating with. Location anonymity isn’t really that important unless you have something to hide that you think someone may try to find you for, though taking appropriate precautions (next few paragraphs) could never hurt. TOR is actually probably more hurtful in the long run since the exit node is an untrusted user who can spy on your unencrypted traffic.
Now, if you really wanted an appropriate solution for privacy (not anonymity), you only ever let your unencrypted traffic exit out of trusted networks. This generally means your house (and maybe your office), though even from those places their ISPs could easily “spy” on your unencrypted traffic. And technically, any router in between you and the server you are connected to can spy on your unencrypted traffic, though there is too much traffic going on for anyone in between ISPs to really even want to try this sort of thing. So it’s not a bad idea to set up a VPN server at a secure locations for yourself so you can connect in and route your traffic through the secure location when you are anywhere on the planet. For this I would recommend OpenVPN, and make sure you configure your client to route all traffic through the VPN tunnel. This approach could severely reduce your connection speed as most broadband connections have a much lower upload than download (meaning when your VPN server sends data back to you, it’s most likely slower than you would normally get it).
However, the speed issue can be solved by setting up your VPN server at a collocation (or on a cloud like Amazon’s), as these collocation ISPs route through so much traffic it would be unfeasible for them to snoop, nor often would they have as much inclination to do so. This wouldn’t give great anonymity since only a handful of people would most likely be using these VPNs, and they will generally exit from the same IP address, but it gives a great amount of privacy when on untrusted (or any) internet connection, and there are no noticeable speed decreases if at a good collocation.
The best solution is to use a paid-for VPN service. However, you would have to of course trust this service to not be spying on your unencrypted traffic, which they generally wouldn’t do. These services are good because they (should be) fast, they are secure exit points, and best of all they can be anonymous to a large degree. Since so many people are coming from the same exit points, and your exit point’s IP could change in between each connection with these VPNs, there’s no easy way to know who the traffic is coming from on a monitoring perspective outside of the VPN provider.
However, there are also downsides to using these VPN services since many providers depend and filter based on location data. For example:
If you are coming from outside of the country many services inside the USA may block you
Providers needing your location to provide a service for you would have the wrong location. For example, Google Maps wouldn’t know what area to search around when you asked for “restaurants”. You would have to specify “restaurants around my address”
Some banks and services check to make sure you are always coming in from the same IP addresses. If you aren’t, it makes you go through additional, often convoluted, security checks.
Some networks you may connect to (hotels for example) may also block VPNs, which can be a major pain. However, I can usually get through using dynamic SSH tunnels (“ssh -D” for a socks proxy) at the very least.
If I were to recommend a paid-for VPN service, it would be PirateBay’s ipredator. This service was set up to help the people of Sweden get around some bad laws passed regarding user privacy. I’m sure they have enough users so you would become one of the crowd, and The Pirate Bay has proven themselves to be trustworthy advocates of internet freedom.
1Modern browsers include the domain you are visiting in the https connection packet in plain text, via the Server Name Indication TLS extension. This means if someone is snooping on your packets, they will see the domain you are visiting via https.
There are two primary authentication methods for logging onto an SSH server as a user. The first is password based authentication, and the second is public key authentication. The public/private RSA key pair for public key authentication can be created using OpenSSH’s “ssh-keygen” application.
I’m not going to go into the exact method on accomplishing this because instructions can be found on countless other places on the internet. However, I was curious yesterday as to what exactly was in the public key (.pub) files created by ssh-keygen, as the data payload was larger than I expected (2232 bits for a 2048 bit key). I couldn’t find documentation on this ANYWHERE on the internet, so I downloaded the OpenSSH source code and looked at the generation code of the files. The format of the files is as follows:
The public key files are ASCII based text files with each public key taking up exactly one line.
Each line is formatted with 2 pieces of data as follows:
KEY_TYPEDATA_PAYLOAD
KEY_TYPE is the type of public key, which in our case (and most cases nowadays) is “ssh-rsa”.
DATA_PAYLOAD contains the actual public key information encoded in base64 with the following format:
I have been using and recommending Thawte’s freeSMIME email certificates for a number of years. Personal email certificates have always been a bit more attractive for me than PGP for communicating securely with other [not always very computer literate] people since they are directly integrated into most [if not all] email clients.
It’s always been nice to be able to sign an email to another person with my certificate, and just tell them to hit the “encrypt” button next time they send me something either of us want encrypted :-) (email clients automatically store a certificate after receiving it, which signing includes).
I have been using PGP for a few years to communicate with multiple people too, and have decided to try and move all my friends/clients over to it too due to the circumstances. Also, PGP has the major advantage of you creating your own private keys instead of a 3rd party (i.e. Thawte) doing it, meaning only you have the key to access emails encrypted to you.
So anywho, here’s the info on getting PGP set up with Thunderbird in Windows for anyone that needs it.
First, of course, you’ll need Thunderbird, which can be downloaded here.
I recommend you always send all your emails in both HTML and Plain Text, so you can have rich text formatting in your emails by default, but lame people that don’t have clients that read HTML are ok too. To do this, go to Menu > Tools > Options > Composition > General > Send Options > In the top box change it to “Send the message in both plain text and HTML”.
When you run GnuPG for the first time, it’ll ask you if you want to generate a key, which you’ll want to do, unless you already have one made that you need to import.
Next, you’ll want to install Enigmail for Thunderbird. After downloaded it, in Thunderbird, go to Menu > Tools > Add-ons > Extensions > Install, and open the .xpi file.
After Thunderbird restarts, go to Menu > OpenPGP > Setup Wizard and step through it. During this setup, I personally suggest changing the following default options:
“Do you want to change a few default settings...” > Yes > Details > Uncheck the following
Disable flowed text
View message body as plain text
Use 8-bit encoding for message sending
Do not compose HTML message
To encrypt mail to other people, or verify a signed message from them, you need their public key file. Some of the ways they can send their public key to you are as follows:
A normal file send, in which case you will need to import it through GnuPG.
You might also be able to retrieve it from a public key server if they put it there, but I am not going to go into that.
If they send it to you through an attachment in an email, and you double click on it in Thunderbird, you will receive a prompt asking if you’d like to import the key.
To encrypt an email to another person, after having their public key, simple go to Menu > OpenPGP > Encrypt Message in the compose window. Make sure to also check Menu > OpenPGP > Use PGP/MIME for This Message so it can send the HTML!
To send your public key to someone go to Menu > OpenPGP > Attach My Public Key in the compose window.
On computers equipped with certain brands of audio cards, when performing the system encryption pretest or when the system partition/drive is encrypted, the sound card drivers failed to load. This will no longer occur. (Windows Vista/XP/2003)
It is possible to access mounted TrueCrypt volumes over a network. (Windows)
I am quite impressed that they did this so quickly, and am sad I did not find out until now. They also fixed the other missing feature I reported to them within a month of that [version 5.1]
Support for hibernation on computers where the system partition is encrypted (previous versions of TrueCrypt prevented the system from hibernating when the system partition was encrypted). (Windows Vista/XP/2008/2003)
Also in the version history [5.1a], this little paragraph made me smile
[Update 2008-04-02: Although we have not filed any complaint with Microsoft yet, we were contacted (on March 27) by Scott Field, a lead Architect in the Windows Client Operating System Division at Microsoft, who stated that he would like to investigate our requirements and look at possible solutions. We responded on March 31 providing details of the issues and suggested solutions.]
Other very important features they have added for version 6.0 that I am super happy about:
Embedded backup header (located at the end of the volume)
Up to 20% faster resuming from hibernation when the system partition/drive is encrypted. (As I have always been super frustrated by super slow hibernation resume support on my now abandoned partition encryption software suite, BestCrypt.)
Multithreading support (Faster parallel processing, yay)
I did some speed tests of hibernation support in XP and got the following numbers: (Results are averages of at least 5 tests, in seconds)
*VMWare was running with 256MB of RAM and 1 virtual CPU on Laptop**. VMWare results were not always stable due to other processes on the host machine, so I terminated the worst offenders
**Laptop is a 2.4ghz Pentium Core Duo with 2GB RAM and 60GB hard drive running at 7200RPM
The decoy (first) partition holds a decoy OS and is accessible from the password prompt (password #3) at bootup. You should not have any sensitive data in it, and can give out the password if need be. TrueCrypt recommends using this decoy OS at least as much as the hidden OS so if someone checks out the decoy they are not suspicious of it. If the perpetrator is suspicious of the decoy due to non use, the size of the partition, or just the fact that you have TrueCrypt installed, you may need to fall back onto the second stage of the security in the below paragraph.
The outer (second) partition holds some decoy files and a hidden volume inside of it. It is accessible by either the decoy or hidden OS by opening the partition through a normal TrueCrypt device mounting (password #1). It is recommended to give out its password only if you have already been forced to mount your decoy OS and the perpetrator suspects a secure partition as is explained in the above paragraph. If any data is written to it after creation, it can destroy information at random within the Hidden OS (see “Partition Sizes” at the bottom).
The hidden partition holds its own OS and is hidden within the outer (second) partition. It is accessible from the password prompt (password #2) at bootup or by mounting the partition from TrueCrypt as a device when the decoy OS is open. The decoy partition/OS is NOT accessible while the hidden OS is open.
Basic installation procedure:
Create a computer with 2 partitions. The second (outer) partition must be 5% larger than the first (decoy) for a FAT file system, or 110% (2.1x) larger for a NTFS file system (see “Partition Sizes” at the bottom). You might as well make the outer partition FAT since it won’t be used much, if at all, and this won’t affect the hidden partition.
Install your operating system on the first (decoy) partition with all of your applications and data that are not sensitive.
Run the TrueCrypt hidden install, this does the following:
Asks for outer volume password (Password #1). Creates and formats the second (outer) partition/volume.
Lets you copy some “sensitive looking” files to the outer partition. Nothing should ever be changed or added to the outer partition after this, see “Partition Sizes” at the bottom.
Asks for hidden volume password (Password #2). The hidden partition is created within the outer partition.
Asks for decoy volume password (Password #3).
Rescue disk is created
All data from the first (decoy) partition is copied to the hidden partition, and then all data from the first (decoy) partition is encrypted.
And finally, things that bugged me, because I like to vent :-) :
Forced creation of rescue disk on full volume encryption. Having the file is more than enough since it can be copied to other hard drives, but it wanted proof of the rescue disc creation, so I just mounted the ISO to a virtual drive.
No customized pre-boot screens. This isn’t important really, but I loved my hokie ASCII art ^_^;.
Partition sizes: The hidden OS partition will be the exact same size as the decoy and the outer partition must be at least 5% larger for FAT and 110% larger for NTFS than the decoy.
The hidden OS partition will be the exact size as the decoy partition because they are originally duplicates of each other, including their original partition tables, which include the size of the partition.
The outer (second) partition that holds the hidden partition must be at least 5% larger for FAT and 110% larger for NTFS than the decoy. The reason for this is the file contents tables. NTFS, unfortunately in this case, stores its file table in the middle of the partition. The outer partition’s file table does not, however, affect the hidden partition in any way.
So, for example (these numbers are theoretical, I am not entirely sure if these are correct), if we have a 2GB decoy partition, the outer NTFS partition must be at least 4.2GB and the hidden partition will be 2GB. If we made the outer partition 6GB, then 0-3GB would be writable, 3.0GB-3.6GB would be used for the file table, 3.6GB-4.0GB would be writable, and 4.0GB-6.0GB would be used by the hidden operating system. So, theoretically, you could write 3.4GB to the outer volume before problems started occurring, but I wouldn’t trust NTFS to only write to the beginning of the drive.
Just as is the case with windows, where you never install before at least the first service pack is released, so is the case with TrueCrypt, it seems.
TrueCrypt is open source, which is a major plus, and in my opinion, the best solution for encrypting data. In a nutshell, TrueCrypt allows the creation of encrypted “container files” that when mounted act as a hard drive partition, accessible through a password and/or a key file. The encryption, security, and speed are all top notch and the program runs completely transparent to the user after volume mounting, so I would highly recommend the program to anyone that has anything at all to hide :-).
It also has some other useful options like the ability to encrypt USB flash cards for opening at other locations without having TrueCrypt installed, and “hidden container files” in which a second hidden volume is contained within the same container, unlockable by a separate password/key file, which is great for plausible deniability. I have been always been a fan of TrueCrypt since I first found and adopted it years ago, and would highly recommend it.
Unfortunately, TrueCrypt 5.0, which was just released a few days ago, does not yet meet quality standards. It does all the old stuff it used to of course, and adds some great new features, but the multiple bugs I have found are forcing me to revert to an older version of it, and back to other 3rd party applications I have been using for other types of encryption.
The new feature, which I’ve been looking forward too for ages is pre-boot authentication volume encryption, which basically means encrypting 100% of your hard drive (partition) that contains Windows (or another OS) on it so you only have to put in your password during boot, and EVERYTHING is encrypted and safe, and impossible (by today’s standards) to access before the password is put in. This is especially important for laptops due to the increased likelihood of it falling into others’ hands through loss or theft. Unfortunately, full volume encryption has broken 2 things; the ability to put my laptop into hibernation (which was also a problem with other volume encryption programs I’ve tried in the past), and oddly enough, it broke my audio drivers so I have no sound XD. So, I’m reverting back to BestCrypt Volume Encryption [v1.95.1], which I’ve also been using for quite a while, that does the same thing, but allows hibernation. My only beefs with it are that it’s closed source, something that isn’t usually a problem in my book, but is for this case [security], and that hibernation is SLOW, probably due to the fact that it can no longer use DMA, due to needing to pass data through the CPU for encryption. Another, technically not so important, feature TrueCrypt doesn’t include yet that most other volume encryption pre-boot authentication packages include is customized boot password prompt screens. I’ve included my incredibly dorky screens (for BestCrypt Volume Encryption) below :-D.
The other thing that is broken, oddly enough, forcing me to revert to TrueCrypt 4.3a, is I can’t mount containers over a network anymore through Windows File and Print Sharing :-\. Ah well, hopefully they’ll get these things fixed soon enough.
My boot password prompt, and no, I will not explain it, except that DarkSide was my previous computer handle a very good number of years ago.
A boot prompt I made for a female friend, weeee, ASCII art ^_^;.
Note that when creating a screen for BestCrypt Volume Encryption, the characters 0x08 0x09 0x0A 0x0D are all invalid. The “&” is used to place the password prompt.
One other Volume Encryption I tried, which was just about as good, though I do not recall if it allowed hibernation, was DriveCrypt Plus Pack [v3.90G]. It also allowed bitmaps [pictures] for the boot password prompt screen.