Setting up a Server
- Connecting and Creating a User
- SSH Clients
- Creating a User
- Configuring and Securing SSH
- SSH Daemon Configuration
- Additional Measures
- Transferring Files
- The SFTP Server
- SFTP Clients
- SCP
- Removing Unused Services
- Detecting Running Services
- Disabling an Init Script
- Running a Web Server
- Nginx General Configuration
- Managing Multiple Sites
- Individual Site Configuration
June 7, 2011
Revised June 22, 2011
With the emergence of virtualization software, running a personal server has become very affordable. It is now possible to get full root access on your own small virtual private server for only a few dollars a month. Some of the more common uses for a VPS include:
- Hosting your own website
- Backing up your files
- Running a proxy server to facilitate anonymous web browsing, or to bypass a firewall
- Using the fast connection to download and seed torrents
- Running a streaming audio/video server
This article will cover the basics of setting up a server to accomplish some of these common tasks.
Operating Systems
CentOS and Debian are arguably the two most popular Linux distributions for a server. Both are excellent choices, even in a resource constrained environment.
I personally run Debian Linux on my machines, hence some instructions may be Debian-specific. However, I would expect configuration files and options to be mostly OS-agnostic. Finally, this article assumes familiarity with basic Linux commands (e.g. ls, man, etc.) and file editing.
Related Links
- Low End Box is a listing of affordable VPS offers and has a great community of users who share their experiences with various hosts.
- Web Hosting Talk is a heavily frequented forum with deals and reviews on web hosts (including VPS hosts)
Connecting and Creating a User
SSH is the de facto means of connecting to a Linux server remotely. SSH, which stands for Secure Shell, is a protocol that employs encryption techniques to ensure private and secure communication between two parties.
SSH Clients
In order to use SSH, one requires an SSH client on the local computer and an SSH server on the remote computer. I recommend the following SSH clients:
- Windows: PuTTY is a lightweight but powerful client that will meet the needs of most users.
- Linux: Most linux distributions come pre-installed with OpenSSH. Otherwise, Dropbear is a nice lean alternative.
On a purchased or leased server, the hosting company is responsible for providing the user with the IP address of their server and an SSH login account (often times the root account can be initially used to login). Consult your SSH client documentation if you need instructions for connecting to a server.
Creating a User
It is generally considered inadvisable to login as the root user for security reasons. Hence one of the first tasks on a new server should be to create an unprivileged user to use as a general login account.
The interactive program adduser can be used to walk through this process. However, a more quick and dirty approach is to run useradd with a short set of arguments:
$ useradd -m -G [groups] -s [login_shell] [username]
Once a new user is created, the current SSH session should be terminated and one should reconnect as the newly created user.
From now on, if root permissions are ever needed the command su can be used. This command will first prompt for the root password and then grant root privileges. Alternatively, consider installing sudo which allows running individual commands with a different user's permissions (including root).
Configuring and Securing SSH
The SSH Daemon
On most servers, there is software running in the background that listens for incoming SSH session requests. This software, called the SSH daemon, is what allows a user to remotely establish a connection at any time.
Shortly after going online, your server may start to receive break in attempts via SSH. The first step in securing the server is limiting how the SSH daemon responds to incoming requests.
SSH Daemon Configuration
The file /etc/ssh/sshd_config is what typically controls the behavior of the SSH daemon on an OpenSSH installation. I suggest considering some of the following configuration options (uncommenting or adding the ones that are not in the existing file):
# Pick a non-standard port number
Port 2200
# Protocol 1 is not as secure as 2
Protocol 2
# Prevent remote root login attempts
PermitRootLogin no
# Only allow your user to login
AllowUsers yourUsername
# Limit number of authentication tries per session
MaxAuthTries 2
# Automatically disconnect after x seconds if no
# successful login has occurred
LoginGraceTime 30
# Randomly drop additional simultaneous connections
# starting with a probability of 50% at connection 3
# and increasing linearly up to connection 10
MaxStartups 3:50:10
# Automatically terminate idle SSH sessions
ClientAliveInterval 300
ClientAliveCountMax 0
# Separates the daemon process into a privileged
# and unprivileged part for security
UsePrivilegeSeparation yes
# Ensure the SSH directories and files have appropriate
# permissions and ownerships before allowing new sessions
StrictModes yes
Make sure to test any changes made to this configuration file before disconnecting the current session; if a mistake was made, it may be impossible to establish future connections. Testing the configuration can be done by reloading the SSH daemon (which will not kill existing connections) and then attempting to establish a new SSH session.
$ /etc/init.d/ssh reload
Additional Measures
If further protection against brute force attacks is desired, solutions such as Fail2ban, or DenyHosts can be deployed. These programs can be configured to have a server automatically block IP addresses after too many failed login attempts.
Other approaches include using public keys for SSH authentication and configuring the Linux firewall to limit SSH port access.
Transferring Files
There are many ways to transfer files to and from a server. I like to use SFTP because it is a secure solution that doesn't require installing additional software on the server. One of the great things about SFTP is that it is often ready to use immediately after SSH is set up.
The SFTP Server
Most of the time OpenSSH installations comes pre-configured to serve SFTP. To verify this, just check that /etc/ssh/sshd_config contains a line similar to:
Subsystem sftp /usr/lib/openssh/sftp-server
SFTP Clients
A client is required in order to transfer files to a remote server using SFTP. I recommend the cross-platform FileZilla which is free, open-source, and one of the most popular downloads on SourceForge. Other options include WinSCP for Windows and the command line program sftp for Linux. Standard SSH login credentials can usually be used when transferring files with SFTP.
SCP
If only transferring a few files between Linux machines or if a command line interface is preferred, I prefer scp over SFTP. Using the program is straightforward and similar to cp:
$ scp user1@host1:/path/to/source user2@host2:/path/to/dest
Removing Unused Services
Most operating systems start some unneeded services at boot time. By preventing unused services from automatically starting, a system's limited resources can be conserved (this is of special importance on a small server).
Detecting Running Services
The command ps aux will print a list of running processes. Once a suspicious process has been identified, verify that it is a service by locating a corresponding init script in the /etc/init.d directory. Init scripts are the files responsible for starting, stopping, or reloading a service.
Disabling an Init Script
Before removing a service from the boot process, research the internet to confirm that the service is not critical to the functioning of the system. The services cron, syslogd, and sshd are all important and should typically never be disabled.
Unfortunately, modifying which services start at system boot is often operating system dependent. On Debian Linux you can manage services using the command update-rc.d.
# Remove a service from startup
$ update-rc.d script_name remove
# Restore a service to startup
$ update-rc.d script_name defaults
Running a Web Server
A common use for a personal server is to host a website. While Apache is the most popular HTTP server, I tend to prefer Nginx because it consumes less resources. Both solutions are widely used in small and large scale production environments.
Nginx General Configuration
Nginx configuration is driven by /etc/nginx/nginx.conf. Here is a sample configuration file for a small server, including some recommended options for security:
# The user that the server runs as, make sure it is underprivileged
user www-data;
# Number of workers the server spawns; two is often sufficient
worker_processes 2;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
# No. connections a single worker can handle
worker_connections 1024;
}
http {
# Serve different file types to clients properly
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Timeouts (can assist against denial of service attacks)
client_body_timeout 30;
client_header_timeout 30;
keepalive_timeout 30 30;
send_timeout 30;
# Set these low to mitigate buffer overflow attacks
# Tweak if your server accepts large form uploads
client_body_buffer_size 64K;
client_header_buffer_size 64K;
client_max_body_size 1M;
large_client_header_buffers 1 1k;
# Don't print server version
server_name_in_redirect off;
server_tokens off;
# Ignore garbage headers from clients
ignore_invalid_headers on;
# Allow nginx to check multiple locations for a file
recursive_error_pages on;
# Can increase performance when sending large files
sendfile on;
# Logfile Format
log_format main '$remote_addr $host $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" "$http_user_agent" '
access_log /var/log/nginx/access.log combined;
}
Managing Multiple Sites
Oftentimes the nginx.conf will contain a directive to include additional configuration files. This functionality is typically used to simplify serving multiple websites. For example, I have the following in my nginx.conf:
http {
# [...]
include /etc/nginx/sites-enabled/*;
}
This allows a server administrator to easily manage multiple sites by maintaining separate configuration files for each site.
Individual Site Configuration
Once server-wide configuration parameters have been established, one can create configuration files for each site that is to be served. Here is an example site configuration file (e.g. /etc/nginx/sites-enabled/my_site) that demonstrates some commonly used Nginx functionality:
# redirect requests for www.mysite.com to mysite.com
server {
listen 80;
server_name www.mysite.com;
rewrite ^/(.*) http://mysite.com/$1 permanent;
}
# main site configuration
server {
# port for listening to requests
listen 80 default;
server_tokens off;
client_max_body_size 1M;
# helps nginx direct traffic if serving multiple sites
server_name mysite.com;
# the root path for website files
root /var/www/mysite;
# raise a 404 error for requests containing 'forbidden_dir'
# (e.g. http://mysite.com/foo/forbidden_dir)
location ~* /forbidden_dir/ {
return 404;
}
location /special_dir/
{
# map http://mysite.com/special_dir to a location outside
# of /var/www/mysite
alias /var/www/special_dir/;
}
location /img/
{
# don't log requests to the 'img' directory
access_log off;
# tell the client to cache files in 'img' for 30 days
expires 30d;
}
# direct to '/50x.html' in the event of a server error
error_page 500 501 502 503 504 505 506 507 /50x.html;
error_page 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 /50x.html;
location /50x.html {
internal;
}
}
