A month ago I have discovered new world of cheap dedicated servers. If you hear a term “Dedicated Server” you probably imagine powerful machine located in a data-center and with price around $60/month or more. But nowadays you can rent something less expensive, from $6 to $15, with 0.5-1TB drive and unlimited traffic. It is ideal solution for personal data warehouse, own e-mail server f course nowadays (especially after Snowden affair) security of stored data is important. Secured lines and encryption is now essential. But because you do not have a physical access to the server encryption can be difficult because you have to “unlock” encrypted container during boot and it is usually done by typing password on the server physical console or by a dongle inserted to the server. Nothing from that is possible with remote access only.. But several days ago I found great idea how to solve this problem on the Internet. The Encrypted Linux Dedicated Server with drive unlocked remotely by SSH temporary login. I tried to configure my server and it works flawlessly!
At the beginning I have to say that you can find many very similar or simple copy/pasted posts about the topic on the Internet. But no one fit all my needs or works without problems. Due this I have prepared my own recipe compiled from many resources and I have made decision to publish it on my site to give chance to other users to save time necessary for research how to fix some problems or annoyances. I can’t make impression that whole recipe is my own research and push original authors to the dark. You can find all my resources at the end of the post and you can use it for your own research. Of course you can do this with my post too.
Where to Get the Server
After the short introduction we can start with real work. First requirement is to get your own server somewhere in the Cloud. One of the best options is to get the server from the Kimsufi provider. But problem with the Kimsufi is that you have to “hunt” your own server because number of customers waiting for the server is much bigger then number of available devices. So you have to use some tools and check Kimsufi pages carefully to get own server. But it’s possible. I had used same way and have been successful.. :)
Next option can be ServDiscount, with little bit higher price, but you can choose your device quickly and easily.
Finally I can mention Hetzner site, where you can get your server in auction of abandoned devices. If you have another nice provider with offer of chap dedicated servers, let me know in discussion below.
When we have access rights to the new server, we can proceed with configuration. All providers offer a one click installation of a Linux distribution. But this option is not easy to use for our purposes - to modify it for full encryption. Instead of the one click installation we have to boot the server to the Rescue Mode to get full access to the hard-drive and connect to the server remotely with SSH. This option is offered by all providers because it allows to fix some problems with device remotely. For example when kernel update blocks the server to boot. So boot to the Rescue Mode and when you are logged-in we can proceed with next step.
Create Partitions
When we have the SSH access we must detect the hard-drive and modify its partition scheme. To display the disk scheme, use for example this command:
|
|
Here we can see that the main hard-drive is here known as sda with one main partition sda1. Main purpose of the command was to detect the drive name, in our case sda. Now we have to re-partitioning the drive for encrypted LVM purposes.
!!WARNING!! These steps completely destroy any data on the drive so be sure that you will not lose anything important!!!
Use the fdisk command to create new partition table:
|
|
The fdisk use something as text based menu, so we have to provide several steps in right order and then write new partition table to the disk.
- Empty the current table by command (o)
- Create new primary partition 1
- command (n)
- primary (p)
- Number 1 (1)
- Default first sector (Enter)
- specify size (+250M)
- Create new primary partition 2
- command (n)
- primary (p)
- Number 2 (2)
- Default first sector (Enter)
- Default last sector (Enter)
- Make partition one bootable
- command (a)
- Number 1 (1)
- Verify result by print the table command (p)
- Write new table to the disk command (w)
Now verify the result again to be sure that everything is ok.
|
|
If you see something similar, you can continue with creating encrypted disk space. But before that we can improve the strength of the security by randomization of the disk space
Randomize Disk Space
Due safety reasons is recommended to fill the space for encrypted files by random pattern to make the encryption stronger and disable possibility to analyze patterns on the drive by attacker. This step is optional and can be time consuming (hours or days) but I don’t recommend to skip it. Best solution to do that is to use the Screen application - the full-screen window manager that multiplexes a physical terminal between several processes. With the Screen you can start any process inside it, then detach from the console and let it run in the background. Even you disconnect your SSH session, the Screen is still running with all tasks fired inside it. You can anytime connect to the server by SSH, attach back to the Screen console and check the task progress.
To start your Screen session type the screen command on the console and press enter. Then try to run any command - for example date
|
|
Now press the Ctrl+A and then D. This will detach you from the actual Screen session
The result of the date command now disappear and you can see something like this:
|
|
Important thing here is a number - in our case 1381 - it is the running screen session number Now type:
|
|
If everything goes well, you can see again the result of the date command because you has been attached back to the running Screen console session. Of course you can fire simultaneously multiple sessions. Just type screen again when you are detached from the Screen console. It fires a new clean session for you. To get list of active running Screen sessions just type:
|
|
Then you can attach back to the selected Screen console with selected session number by same way as described above.
With the Screen command knowledge we can fill the partition with random numbers in the background task. Just type this inside the Screen session:
|
|
This will start filling the second partition (where an encrypted system will be created) by random numbers. Because it can takes long time you can improve this command by monitoring progress of the filling process. To do this correctly you have to know approximated size of the filling partition. Use the lsblk command and read the sda2 partition size here. In my example it is 931.5G. When you know the partition siz modify the command for partition filling by this way:
|
|
The pv command will show you how many bytes goes through it and the –size parameter allows to the pv command to calculate how many percent of the operation is already done.
Now you can detach from the Screen session and wait expected time (in my case more than 24 hours) to finish randomization process. You can check progress time by time of course. When the task is finished the server is ready for creation of the encrypted space.
Encrypt the Server Space
Now we can continue with configuring the server encrypted disk space. This will hold operating system and sensitive data. For the disk encryption the Linux offers technology called LUKS - Linux Unified Key Setup. This allows to encrypt the disk space transparently and use the encrypted space as classical disk partition but protected by strong cryptography. To configure the encryption on the sda2 partition, use the cryptsetup command with these parameters:
|
|
You will get a confirmation question and then th password query:
|
|
Be sure to type YES here in uppercase as response on the overwrite confirmation question because otherwise the command will fail.
Deep explanation of the cryptsetup command parameters is beyond the scope of the article. If you have any recommendation or notice please let me know in discussions below the article. I refined possible options to my selection above but you can use whatever you want and what better fit your needs. From my point of view is necessary to use a strong hash algorithm as the SHA256 or the SHA512 hash for the password hashing because other hashes are nowadays declared as weak or deprecated (MD5, SHA1 etc.) As encryption algorithm I have selected the aes-xts because AES is declared as standard for high security now and also is supported by new processors hardware so it is quick. Finally I recommend to set the iteration time as high as is acceptable for you because it makes brute force password guessing more time consuming. But of course the same time takes to unlock the partition with your right password. When we mention the password then many recommendations how to create secure and complex password can be found on the Internet. By my opinion 20-25 complex characters is now minimum for good data protection. Select here whatever you find suitable and comfortable for you.
Now dump the LUKS partition UUID and store it for future use:
|
|
Instead of the xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx you will see the real UUID of the partition. Copy that for use in next steps please.
Finally unlock the partition to verify the encryption setup and allow next configuration steps:
|
|
Select the Right Partitioning Scheme
Before next steps we have to make decision about the partition scheme of the server. My experience is that each person has different opinion about that. Of course we have to create swap and root / partitions in all cases, but then somebody say that it is enough, somebody else needs separated partitons for /home /var etc… By my opinion the schema vary based on the server usage purpose. Different schema is suitable for web/mail server, different for server with many users simultaneously logged in and different for the data warehouse. Of course can be good idea to have some flexibility here, if a new requirement will rise up. Due this I have selected the logical disk volume (LVM) mechanism because it is easy configurable and allow on the fly flexibility in the disk layout design. Due security purposes I have used separate temp partition to allow mount it as non-executable. And then I separate system files from my data (it allows better backup possibilities if necessary) so I have root partition for operating system files and srv partition for all my real data.
Here is my server partition scheme:
- root - 15GB
- tmp - 250MB
- swap - (2 x real server memory size)
- srv - rest of the free disk space, or something around 70% of the free space to leave a reserve for future LVM modifications.
Of course you can modify the scheme to fit your needs and habits.
Create the Server Logical Partitions
Now we can continue with LVM and server partitions. At first we have to create the physical volume on the LUKS encrypted sda2_crypt partition. To do this simply type:
|
|
When the physical volume is created we can continue with creation of a Volume Group. The Volume Group with a name sgrp will contain only one previously created physical volume now.
|
|
Finally, we will create logical partitions based on the schema described above on the sgrp volume group:
|
|
Finally you can verify the result by command:
|
|
Create Filesystems
With partitions created we can continue to create appropriate filesystems on those partitions to allow mount them and store files on them. Here you can select from many options too but I’m conservative and use ext4 filesystem here. The ext4 filesystem is used by many distributions by default and it is de-facto standard for the Linux filesystems in those days. Exception here is the swap which must use the swap filesystem and /boot partition where I use ext2 because journal and other advanced features of the ext4 FS are not necessary here and ext2 can be handled easily during recovery process when something goes wrong. Use those commands to create appropriate filesystems:
|
|
Access Disk from Rescue Mode When Necessary
This step can be necessary if you need to boot the server to the Rescue mode again and fix something from this environment or you have to break the configuration process and continue again later. During tune-up process of this How-To I have to do this many times. In this case you have to only unlock the LUKS manually and activate the Volume Group sgrp but don’t create partitions etc again. Repeat partition creation cause to lost all your work previously done!
When you boot the Rescue Mode again, just type these commands:
|
|
You will get the same state as you had after step Create Filesystems and you can continue with mounting partitions and entering chroot environment. Of course, you have to skip the debootstrap here too.
Mount Logical Partitions
To allow to create or modify files on previously created partitions, we have to mount them to same way how they will be used by the server OS in the future. But because we are in the Rescue Mode now, we have to create entry point where the root of the server OS will be mounted. Create the folder /srv_root for this and mount the root partition to this folder:
|
|
When we are doing this first time, we have to create appropriate folders inside the server root. This step have to be one only once, but if you try to do that again you will not get nothing worse then error message.
|
|
Now mount rest of partitions to newly created folders:
|
|
Now activate the swap:
|
|
And finally set appropriate rights for the /tmp folder:
|
|
Now all server partitions are correctly mounted and prepared for next config steps.
Debootstrap
First of all you have to check if the Rescue system supports the Debootstrap command and have the wget tool installed. Try this in the console window:
|
|
I have checked two server providers and on both of them those commands are available by default but if you are not lucky then you have to install them manually to your rescue mode.
|
|
With these tools ready we can continue with preparations for the Debootstrap. To allow the Debootstrap tool to verify downloaded data and check if are not corrupted or modified by an error or an attacker we have to download Ubuntu gpg public keys. These keys signed all Ubuntu packages and protect them against modifications. To download keys please use this command:
|
|
This will download the ubuntu-archive-keyring.gpg file to your home directory. Copy the file now to destination folder by this command:
|
|
As alternative you can use the keyring file directly in the bootstrap process by parameter –keyring but it doesn’t work well for me.
Anyhow if you see any of that messages during the debootstrap process:
|
|
then the keyring is not downloaded or specified correctly and you have to fix it. Now is time to start the debootstrap process. It puts all necessary files for OS root to /root partition now mounted in the /srv_root folder. To do that, just type:
|
|
If you want to install the 32bit architecture instead the 64bit then use the i386 as the –arch parameter. The amd64 specifies 64bit architecture. The ’trusty’ parameter specifies that we can install the Ubuntu 14.04 LTS (Trusty Tahr). It is latest LTS version at time when I write this article. You can of course install different Ubuntu version by change the parameter - for example for 15.10 use ‘wily’ instead of ’trusty’ here. The –keyring parameter specify file with public gpg keys to verify packages integrity and have to be specified as full path, or with current folder ‘./’ prefix. If you copied the keyring to the /usr/share/keyrings/ folder, you don’t need to specify this parameter.
Chroot and Base Config
Now we can switch our session to chroot environment. It is something like virtual access to the OS of our server as it will be booted directly by hardware in the future. This allows to install additional pieces of software and modify configuration files on the server OS instead of modify the Rescue Mode OS files. First step to successfully enter the chroot environment is to mount special filesystems ( dev, proc, sys ) to the root filesystem of the server OS:
|
|
When we are done, we can enter the chroot environment by this command:
|
|
Now welcome into the chroot environment of the server. Since this time all commands typed to the console will modify the server filesystem and configuration instead the Rescue OS environment.
First of all, create the symbolic link from /etc/mtab to /proc/mounts.
|
|
This avoid problem if the root filesystem ( / ) is mounted as Read Only and the /etc/mtab is outdated. This symlink grants that /etcv/mtab is always up to date.
Next good idea connected with filesystems is to force the server to make filesystem checks on each boot. Especially on the server without physical control it can be very good idea. To enable that behavior type this command in the console
|
|
Next essentials thing is to generate appropriate locale files otherwise lot of next steps will be complaining about wrong locale settings.
|
|
Next step is to configure the server clock. Linux servers use usually the UTC time in the hardware clock then we have to set OS to reflect this fact. To do that create file /etc/adjtime by this command:
|
|
Set appropriate time zone for the server by this command:
|
|
Now is granted that files created or modified on the server will have correct time-stamps.
Because lot of configuration steps will be provided by modification of text configuration files then can be nice if you can use the favorite text editor to do that. My preference is vim so I’m installing it immediately. Install whatever you like here instead of vim if it is not your cup of tea.
|
|
Now we have to inform system about the encrypted block device with our partitions and create record about it in the /etc/crypttab file to allow OS correctly handle it. To do this we will need the GUID stored before during LUKS setup. The record will be created by this command:
|
|
where string xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx must be replaced by previously stored LUKS GUID.
Next step is to create /etc/fstab file to allow correct mount of partitions to root filesystem. Each partition is described by one line here. If you do not modified parttion scheme during this how-to you can create file with this content directly:
|
|
Last two lines are commented out but when are enabled then you can allow to move home folder from / to srv partition where all other data reside. The /tmp partition is mounted as non-executable because some attack techniques against the server tries to create a file here and then run it to finalize the attack. It is the reason why I always mount /tmp folder to standalone partition.
Networking
To configure networking correctly you need to know the server assigned IP address and other network parameters. It is defined by the server provider and you can find it in the server administration very often.
You have to know:
- Server IP address ( example: 123.123.123.123 )
- Network gateway IP address( example: 123.123.123.1 )
- Network mask ( example: 255.255.255.0 )
- Your domain name ( example: mydomain.dom )
- Your server host name (example: myserver )
- DNS server addresses (can be replaced by generic Google DNS 8.8.8.8, 8.8.4.4)
When you have collected all necessary pieces of information you can create networking configuration. At first we define the short and full hostname. Type these commands and replace example values by real names:
|
|
At next create the file /etc/network/interfaces with this content and replace example values from above by your real values:
|
|
The last line beginning by pre-up… is necessary here to grant correct network initialization when main system is booted after unlocking by busybox environment. Please leave it here without any change.
Now you can verify the hostname. Type this:
|
|
Instead of myserver.mydomain.dom you have to see your full server name (hostname and domain).
Package Manager and Required Packages
Now we configure the Package manager. Ubuntu is Debian-based system and the package manager config resides inside the /etc/apt/ directory. To handle packages correctly the APT system needs to have a package list of package sources. By the URLs from the list the package manager refresh list of currently available packages and their current versions and based of those pieces of information the package manager allows installation of new or upgrade of current packages. The list resides in the /etc/apt/sources.list file. Ubuntu offers several official package repositories and these are mirrored worldwide by many organizations. Best practice is to set the package manager to use the closest mirrors to the server location. To generate correct list we can use this link: https://repogen.simplylinux.ch/index.php Select here your location and required Ubuntu version. Be sure to select the Universe repository too because it contains some necessary packages (Dropbear). The page finally generates something like this.
|
|
Copy that and paste it to the /etc/apt/sources.list
Additionally modify the package manager to install only required packages - not recommended. It will save disk space and allows better control about server running software. Please type this in the console:
|
|
Now we can install all necessary packages for the server remote unlock mechanism. We can use previously configured package manager.
|
|
BusyBox and Dropbear Configuration
To unlock the server remotely we will use the BusyBox and lightweight ssh server Dropbear with SSH key authentication from the Initramfs. So we have to configure the Dropbear Initramfs config files to allow it’s correct run. The Initramfs config files can be found in the /usr/share/initramfs-tools folder. At first allow to use the Dropbear as part of the Initramfs. To do that edit the Dropbear hook file and remove comment hashtag from the usage directive:
|
|
Remove the hashtag from line above and save the file. Now is necessary to modify the command to run the Dropbear. Default configuration allows all authentication methods include root login with password. This step is missing in all other HowTo posts about the topic and then if the Dropbear is up and running without this mod then brute force attack is possible. Because no strong password is usually set to the busybox root user then it allows to attack the boot environment successfully. To allow only the SSH key authentication and make the Dropbear more secure modify the file:
|
|
Now locate the line
|
|
and change it to this form:
|
|
The 22 number specify the TCP port where the Dropbear will listen for incomming connections. To protect the boot environment against SSH bot attacks you can change this value to your preferred port.
To grant correct network re-initialization after unlock the main system and boot to them we have to modify next file:
|
|
append this line to the end of the file:
|
|
To avoid the Dropbear to run in the main system after a full boot we have to remove it from boot process of the main system. It will be managed by this command:
|
|
Now is time to generate SSH key pair and setup Dropbear to use it. If you are not familiar with SSH key authentication you can read my post The Home Server SSH Remote Access where you can find all necessary pieces of information. So prepare the directory and appropriate file content:
|
|
Paste here the public key and save the file.
Finally when we login remotely to the console by Dropbear we have to unlock the main OS filesystem and continue with boot to it. This will be done by special script. This script is completely taken from the Stinky Parkia blog. You can download the script here (the file is gzipped for security reasons) or copy/paste it from original source to it’s final destination
|
|
Now modify rights to the file to make it executable:
|
|
Now we have to configure the boot networking environment to allow the BusyBox with the Dropbear to be reachable from the internet. We will need again values used to configure the /etc/network/interfaces file here. Edit the file:
|
|
And locate here the line beginning with this text:
|
|
Then add next line bellow the DEVICE line:
|
|
The line contains networking configuration parameters. First is IP address of the server, second (separated by double colon) is IP addres of the gateway, third is the network mask. Please be case sensitive here and do not provide any spaces. Of course replace my example IP address and gateway values by correct values for your server (see my example above).
Finally we nave to disable the Biosdevname mechanism to disable new network devices naming convention. If we do not do that we risk that network will not work correctly because on some systems (one of mine is good example) the network card will get name em1 and all network configuration will not work. I didn’t find a reason to use these new device names. If you can give to me a reason please let me know by comment. Anyway to disable this mechanism we nave to modify the boot loader grub config file:
|
|
Now modify lines GRUB_CMDLINE_LINUX_DEFAULT and GRUB_CMDLINE_LINUX to contain this content:
|
|
If those lines contain additional content, please preserve it if you do not know exactly what it means.
Configuration for the OS boot is now finished so we can create the Initramfs image used for first boot and Dropbear start. This will be done by this command:
|
|
This command have to be used always when you modify anything inside the Initramfs config in the future. So remember this command and run it always when you update the Initramfs environment or update the server kernel.
Create regular user account
Finally I create the regular user account in the main OS environment. This account will be used for login to unlocked and functional server and for the server management. Because the Ubuntu uses sudo mechanism for the administration I’ll not break this rule and configure the server to use sudo too.
At first, select the account name. In my case, it’s srvuser Now create the user account and add it to appropriate groups:
|
|
Now we can configure the SSH key for the login as the srvuser. You can reuse the same key as for the Dropbear unlock login or use separated key. Considerations about usage of one SSH key for all accounts or separate SSH key for each account are beyond the scope of this post and is up to you what do you choose. Anyway, to configure the SSH login continue with these steps:
|
|
paste your public key here and save the file. Now continue with setting correct file owner and rights to make the SSH daemon happy and allows it to grant the access to the server:
|
|
Finally, modify the sshd daemon configuration to allow SSH login and improve security. I not describe it here because I have mentioned this in my previous posts
We are now done with the config steps and is time to let the server fly on own wings. We have to exit the chroot environment unmount filesystems and then reboot the server. To exit chroot environment type these commands in the console:
|
|
Now disable the Rescue mode in the server management console and reboot the server. If everything works fine you will be able to connect by SSH client to the server as root with the Dropbear key. You will see something like this:
|
|
Type command for unlock the encrypted disk followed by password after prompt for it:
|
|
If you type the passphrase correctly the encrypted disk will be unlocked and server will continue with boot to the main OS environment. Wait a moment and try to login again but now with key provided for the srvuser account.
Works? Great. Welcome in your own dedicated server with encrypted filesystem. To verify that everything works well continue with some last setup steps.
Final Configuration Steps and Environment Tuning
First one is to set the Network Time Protocol system to make the server internal clock synchronized.
|
|
to verify that everything works well use this command and look for info if the time is NTP synchronized or not.
|
|
Is the time and date correct ? Great!
Finally we have to solve the problem with non-executable /tmp partition… Because the main OS is configured to use /tmp as non-executable partition by default we can get problem to run some scripts when the main OS is up and running. Typical examples of problematic commands are here:
- update-initramfs -u
- apt-get
Here is the solution. For the Initramfs I have created the script to provide the update correctly:
|
|
For the package manager and it’s apt-get command we can use support included directly in the package manager configuration:
|
|
Add here these two lines at the end of the file:
|
|
This is final step in this how-to. I believe that you can reproduce all steps easily and now you have own server ready to solve all your tasks. I’ll continue with some server hardening and then I can use it as the OwnCloud storage. If you are interested in stay tuned. I’ll try to provide similar article for OwnCloud configuration soon.
Finally, here is promised list of sources and references used to create this post:
https://blog.tincho.org/posts/Setting_up_my_server:_re-installing_on_an_encripted_LVM/ https://www.linux.com/community/blogs/133-general-linux/830662-how-to-full-encrypt-your-system-with-lvm-on-luks-from-cli https://fedoraproject.org/wiki/Disk_Encryption_User_Guide#Optional:_Fill_the_device_with_random_data https://stinkyparkia.wordpress.com/2014/10/14/remote-unlocking-luks-encrypted-lvm-using-dropbear-ssh-in-ubuntu-server-14-04-1-with-static-ipst/
I can say thank you to authors of mentioned posts because they helped me a lot to make the server up and running.