This how-to is written for those who would like to set up their first Debian server. It is written for Debian Bullseye, but the following instructions may also work with later versions.
Commands are typed in code brackets and can be copied and pasted into the command line interface of your server. $ in front of the code means that the command should be executed as regular user. # in front of the code means that the command should be executed as root. You can change from regular user to root by typing su - on a system that has root enabled. In order to change to regular user from root, you can type su - yourusername or exit at the command prompt.
1. What is a server?
A server means that a computer is offering functionality for other devices, for instance file sharing, web hosting or printing.
2. Do I need one?
There are several use cases where servers are very handy. For instance, you can use a server to back up your system. You can also put your family photos or music on the server, and it will get easily accessible to all the computers at home. If you install Pi-Hole for your server, you have a powerful ad-blocker that works for your entire LAN.
3. Why no GUI in this tutorial?
Graphical interfaces waste disk space, RAM and they make the system less secure. The drawbacks are bigger than the slight effort you’ll make to deal with it.
4. Hardware
The recommended system requirements are very modest for a server with no GUI. At least have a Pentium 4 with 1GHz. A RAM size of 256 is the minimum requirement, but at least 512 is recommended.
As you can see, If you have a piece of hardware that is too slow for regular desktop use, it can be used as a server. (I use a dirt cheap Raspberry Pi 2 running Debian Bullseye, and it works very well).
5. Installation
5.1 Tips and prerequisites
I am assuming you have installed Debian before, but if you haven’t, the Debian installation manual is a goldmine: https://www.debian.org/releases/stable/installmanual
This image is recommended if you want non-free firmware to be installed as needed: https://cdimage.debian.org/images/unoff ... -firmware/
5.2 Installing Debian
Connect your future server to a keyboard, screen and mouse and proceed with the install.
Select Graphical Install
Select language
Select country, location, territory and locale
Enter hostname. A fitting hostname would be something like server.
Select domain name
Give the root user a password: This howto assumes that you will set a root password for your server. If you prefer sudo, that’s fine, but all the root-commands below will be given as root user. For security reasons, please set strong passwords/passphrases. A server with a root password like "root" toor", "1234" or similar, will likely be hacked the same day if the SSH-server is reachable from the Internet.
Enter the name for the user account.
In partitioning, select Guided – use entire disk and All files in one partition.
Select Finish partitioning and write changes to disk.
Select «Yes» when asked «Write changes to disk?»
When the partitions are finished formatting, the base system is being installed.
Select network mirror.
Leave HTTP-proxy blank unless you have one.
Skip the package survey by selecting «No».
The software selection screen is very important: Only install these: «SSH-server» and «Standard system utilities». If you want to run a web server, you can also enable that.
When asked if you want to install Grub to your primary drive, select «Yes».
The system installation is finished.
After installation, you will be greeted by a black screen.
Just log in using root as login and then enter your root password.
6. Set a static IP
If you are behind a router, some of them will assign the devices behind them the same address every time based on their MAC addresses. If this is the case for you, this step can be skipped.
In case you need to set a static IP, you can follow a few simple steps below.
It is a good idea to make a backup of your old config-file.
Code: Select all
# cp /etc/network/interfaces /etc/network/interfaces.bak
Code: Select all
# apt install net-tools
Code: Select all
# ifconfig
Code: Select all
eth0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 192.168.1.10 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 fe80::ea2a:eaff:feb5:cdef prefixlen 64 scopeid 0x20<link>
ether 28:d2:44:b8:aa:d8 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 20 memory 0xf0600000-f0620000
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 7587 bytes 603393 (589.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 7587 bytes 603393 (589.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@debian:~#
Code: Select all
$ netstat -nr
Code: Select all
hallvor@debian:~$ netstat -nr
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
hallvor@debian:~$
Edit the file:
Code: Select all
# nano /etc/network/interfaces
Code: Select all
# The loopback interface
auto lo
iface lo inet loopback
# The primary network interface
auto eth0
iface eth0 inet static
address 192.168.1.10 #this is the static IP address I want to set
netmask 255.255.255.0 #use the info from the last line above
network 192.168.1.0 #use the info from the last line above
gateway 192.168.1.1 #your router's address/gateway
Make sure you remember your server's IP. You'll need it.
Save with Ctrl+x, then exit with y.
If something went wrong, you can restore the old version with this command:
Code: Select all
# cp /etc/network/interfaces.bak /etc/network/interfaces
7. Make the server ready for connection
If everything seems to work fine after a reboot, unplug the keyboard, screen and everything but the power cord and ethernet cable. Use your computer and try to connect to your server with SSH.
Become root
Code: Select all
$ su -
Now use the Secure Shell Protocol (SSH) to connect to your server. Enter your server's address after @, for instance:
Code: Select all
# ssh root@192.168.1.10
Code: Select all
root@server:~#
8. Navigating with the CLI
If the command line interface makes you feel like a fish on land, there is no need to worry. You have already made yourself acquainted with upgrading, file copying and file editing from the CLI. Not much else is needed.
A few common commands will make it easier to navigate through your server.
ls will list the content of your current directory
ls -la will give extra output, including showing hidden files
cd will navigate to a different directory, for instance cd /home/user/documents to navigate to that directory
cd .. will navigate one step back from the current directory, for instance from /home/user/documents to /home/user
A few more common commands can be found here:
viewtopic.php?t=140728
If you need to edit a configuration file, nano is excellent. Just navigate to the directory you want to edit a file with cd or write the full path after nano, for instance
Code: Select all
# nano /etc/apt/sources.list
https://wiki.debian.org/SourcesList
Edit /etc/apt/sources.list to your liking.
As always, save and exit with Ctrl+x and confirm exit with y.
Update the repositories, download and install the updates.
Code: Select all
# apt update && apt upgrade -y
9. Set up a service
If you just want a file server, you may already have what you need to set up the system. If you run KDE or similar, SSH-connections can be made directly to your server from Dolphin. You can then drag and drop files as if they were local.
Here are some other ideas: Game server, Mastodon-server, Tor-node, mail server, print server and web server.
These examples are NOT TESTED by me. Run at your own risk:
Pi-hole (adblocker) on Debian 11:
https://unixcop.com/deploy-pihole-debian/
Mastodon-server
https://www.linuxbabe.com/debian/instal ... ian-server
Minecraft-server
https://vegastack.com/tutorials/run-you ... debian-11/
9.1 Dealing with services
This command will list all your services and show if they are active. When you install a service in Debian, it will be automatically activated. It is a good idea to stop the service before configuring it. When you are done, just restart the service. No reboot is necessary.
Code: Select all
$ systemctl
Code: Select all
# systemctl disable --now yourparticular.service
Code: Select all
# systemctl enable --now yourparticular.service
10. Security
A lot has been written about security on GNU/Linux servers. A lot of it is sound advice, but there is also quite a bit of questionable advice out there. A few examples can be read here:
viewtopic.php?t=150443
10.1 Keep your server up to date
Services with known vulnerabilities are a huge attack vector. You can get automatic security updates with unattended-upgrades
Install the package
Code: Select all
# apt install unattended-upgrades
Code: Select all
# dpkg-reconfigure unattended-upgrades
A different option is to create a custom script to keep the server up tp date. This script will not only download and install all upgrades. It will also reboot the server if the kernel has been upgraded and clean up downloaded and no longer needed package files. (Thanks to our esteemed member Bloom for helping out with the code.)
First, place the script on the server:
Code: Select all
# nano /usr/local/bin/upgrade.sh
Code: Select all
#!/bin/bash
# Read the current kernel version
current_kernel=$(uname -r|cut -d '-' -f 1)
# Update package list
su -c "apt update"
# Upgrade installed packages
su -c "apt upgrade -y"
# Check if kernel has been upgraded
new_kernel=$(dpkg -l linux-image-*.*|awk '/^ii/{print $2}'|grep -v -e $(uname -r|cut -f1,2 -d"-")|grep -e [0-9]|cut -d'-' -f3)
if [[ $current_kernel != $new_kernel ]]; then
echo "Kernel has been upgraded, rebooting..."
su -c "reboot"
else
echo "Kernel has not been upgraded"
fi
# Clean up downloaded package files
su -c "apt autoclean -y"
Make the script executable:
Code: Select all
# chmod +x /usr/local/bin/upgrade.sh
Code: Select all
# crontab -e
Code: Select all
0 3 * * * /usr/local/bin/upgrade.sh > /var/log/upgrade.log 2>&1
10.2 Run as few services as possible
Services increase the complexity and surface of attack. The leaner you are, the harder you are to hit.
10.3 Configure SSH-server
An SSH-server facing the open Internet is also a common attack vector. We can disable WAN login attempts completely to get rid of such noise:
Code: Select all
# nano /etc/ssh/sshd_config
Code: Select all
AllowUsers *@172.16.0.0/12 *@10.0.0.0/8 *@192.168.0.0/16
10.4 Disable direct root login
If you for some reason need to log in to your server remotely (WAN), it is a good idea to disable direct root login. Any brute-force attack against root will not work, but you will also have to log on to your server with your regular username and password before elevating privileges on the server with su -
Edit the sshd_config-file
Code: Select all
# nano /etc/ssh/sshd_config
Code: Select all
PermitRootLogin no
Restart the SSH-service to apply the changes.
Code: Select all
# systemctl restart sshd
Code: Select all
# ssh hallvor@192.168.1.10
Code: Select all
hallvor@server:~$ su -
Code: Select all
root@server:~#
Code: Select all
# apt install fail2ban
The Debian Wiki has more info regarding SSH, including how to set up passwordless login: https://wiki.debian.org/SSH Fail2Ban would then not be necessary.
10.5 Firewall
Firewalls are pointless if you don't have services listening for connections or if you have opened the ports for all services. If there are services you don't want to expose to the Internet, a firewall is a good idea.
You can check for listening services with one of the following commands.
Code: Select all
# netstat -tulpn
Code: Select all
# lsof -nP -iTCP -sTCP:LISTEN
nftables is the most common frontend to Debian's firewall netfilter. You can install nftables like this:
Code: Select all
# apt install nftables
You can easily replace the example configuration file with this simple ruleset for a server. It will block all incoming connections, except those for port 22, 80 and 443.
Code: Select all
#!/sbin/nft -f
flush ruleset
table inet firewall {
chain inbound {
type filter hook input priority 0; policy drop;
ct state { established, related } accept
ct state invalid drop
iifname lo accept
tcp dport { 22, 80, 443 } accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
10.6 Verify the server's integrity
If you suspect that your system has been tampered with, you can run this command:
Code: Select all
# dpkg --verify
10.7 Further reading
The Securing Debian Manual by Javier Fernández-Sanguino Peña is a highly recommended and comprehensive guide on how to harden and secure a Debian server and services: https://www.debian.org/doc/manuals/secu ... ex.en.html
11. Dist-upgrading your server
In you want to upgrade your server to the next stable version, it's unproblematic to do this over SSH. Please read the release notes for good instructions: https://www.debian.org/releases/stable/releasenotes
That's it. Feel free to share improvements or offer tips on how to install and configure services.
Edit: 05.01.23: Added net-tools, how to disable root login and linked to passwordless login in the Debian Wiki.