cd /
;
apropos
;
You are about to dive into the world of self-hosting.
This document is written to help you host at home or on a dedicated (rented) server some services unfortunately too often entrusted to third parties.
The main goal is to keep things as simple as possible while learning gradually.
Of course, compromises were made. If you feel the urge to learn more after reading this, that's great! π
In order to keep things simple, yet secure, we'll describe the use of OpenBSD OS in its last stable version.
It is known to be safe.
It is also, in my opinion, easy to configure because the same syntax is used by different base tools.
See Why OpenBSD rocks:
https://why-openbsd.rocks/fact/
People say the OpenBSD documentation is great. How can this documentation be useful to me?
OpenBSD's manpages are amazing for sure, use them as a reference.
I see this documentation as an entry point, not a replacement, explaining the fundamentals along with a few tips. Anyway, manpages are great and you should read them too.
You'll see, hosting your server isn't that difficult and is mostly text-editing. Everyone should be able to do it.
Let's go!
Most website you're used to read -- emails, social networks... -- are hosted on computers somewhere in the world. They are only used to serve content to other computers, so we call them "servers". The biggest difference from most people's point of view is that "they don't have a screen".
When you want to read your mail, a client (a webmail, Thunderbird...) asks the server to retrieve your messages. A copy of them is then downloaded on your computer. In "real life", that would look like this:
Hey, mailman, do you have anything for me?
Yes, a postcard from your mom. I'll give it to you as soon as the copier has finished printing it.
Of course, you can ask the post office to delete the message. But how can you be sure ALL copies have been deleted?
Better become your own post office, don't you think? π
At first, everyone was supposed to make a part of the web. Now, most of us depend on private companies that don't respect our privacy.
Arguing that you don't care about the right to privacy because you have nothing to hide is no different than saying you don't care about free speech because you have nothing to say. -- E. Snowden
Read about "Nothing to hide" argument.
https://en.wikipedia.org/wiki/Nothing_to_hide_argument
In this document, we assume that:
This document is not a duplicate of the official OpenBSD FAQ. You should ALWAYS refer to official documentation and manpages when available.
For those who need to read the FAQ offline, I keep an up-to-date archive downloadable from my server:
You don't need phenomenal power to self-host. Start with a machine you have retired because it is too weak for office use.
If you want to buy new hardware, check if it's suported by OpenBSD first:
https://www.openbsd.org/faq/faq1.html#Platforms
ARM architectures don't require much power.
https://www.openbsd.org/arm64.html
If you don't know where to start, APU2 are quite amazing: not too expensive, small, silent, they require less than 10W and are well supported. Actually, this documentation is hosted on an apu2d0.
Take a look at bsd-hardware too and do not hesitate to contribute.
https://bsd-hardware.info/?d=OpenBSD
RPi are supported from 3rd version.
Read the instructions carefully as you will need some files too boot correctly.
https://ftp.openbsd.org/pub/OpenBSD/7.4/arm64/INSTALL.arm64
Make sure you read the official documentation on installing OpenBSD.
https://www.openbsd.org/faq/faq4.html
There really isn't much to say here because the installer explains a lot.
When in doubt, just use the defaults π. This is especially true for disk slicing.
Read about the commands for the disklabel editor if necessary.
https://man.openbsd.org/man8/disklabel.8
Oh, you may want to set up Full Disk Encryption during installation by the way.
https://www.openbsd.org/faq/faq14.html#softraidFDE
You also should install all the sets or make sure you understand what you don't want to install.
If you don't have reliable internet access, or if you want to experiment before setting it up at home, you can rent a server or a virtual host. I've had good experience with:
There's more of course π
When you turn on your server, whether it is connected to a monitor or through SSH, you will see a command prompt:
acdc $ β
Enter commands to manage your server.
There are a lot of them, however we usually use a few of them daily. You'll find more over time.
For now, let's see a few of them. Don't try to memorize everything all at once -- come back and get what you need when the time comes.
By using the "tabulation" key βΉ, you can complete a command or a path. Start writing the beginning, then press βΉ.
Tab is a-ma-zing! π
To erase what you are writing, press "ctrl" and "c" simultaneously. This will also stop most process.
Although this is very rare, some filenames sometimes contain spaces " " or even strange symbols. However, a space is interpreted as a separator between files, so the shell will assume that you are referring to different files instead of just one.
In this case use "\" to "escape" the weird symbol. That way the shell will ignore it. For example:
/path/to/some/file\ with\ spaces.txt
In any case, avoid creating files with strange names.
If you need to treat a large number of them, check out the detox tool (port of the same name).
To find the history and quickly relaunch an old command, use the shortcut "ctrl-r".
You must first enable it by adding this line to the file ~/.profile:
$ echo "export HISTFILE=~/.history" >> ~/.profile
The next time you log in, the history will be active.
You can send a process to the background with "ctrl-z". You can then run new processes.
To resume the previous process when ready, run "fg".
If you have multiple processes in the background, run "jobs -l". Example:
> jobs -l [2] + 65085 Suspended systat vm [1] - 99389 Suspended top -s .5
fg will restore the previous process sent to background, in this case systat (+). You may also specify the desired job by its id:
$ fg 99389 # resume top
See the ksh(1) manpage for more π
Enter the command "su -l" followed by the password for the root user.
β WARNING: For this to work, your user must belong to the "wheel" group. This is the case for the first user created on a system.
You can also configure doas to run a command with superuser privileges as follows:
doas command
Edit or create the /etc/doas.conf file and add:
user-name permit
Replace "user-name" with your, well, username.
See also "man doas"
Enter ls to list the content of the current folder, or follow it with a path to some other folder.
The -l option also allows you to display permissions, owners, sizes and modification dates.
Example:
$ ls -l /etc drwxr-xr-x 7 root wheel 512 Apr 19 19:12 X11 drwx------ 2 root wheel 512 Apr 19 18:16 acme -rw-r--r-- 1 root wheel 1542 Apr 13 15:39 acme-client.conf -rw-r--r-- 1 root wheel 1764 Nov 28 13:56 adduser.conf drwxr-xr-x 2 root wheel 512 Apr 19 18:16 amd drwxr-xr-x 2 root wheel 512 Apr 19 18:16 authpf -rw-r--r-- 1 root wheel 30 Aug 2 2020 boot.conf [...]
We get one line per file/folder. Each line has these fields:
<permissions> <inode> <owner> <group> <size> <date of last access> <file name>
A simple and yet efficient method to secure your website -- and the server it lives on -- is to adjust the permissions and the owner of its files.
Read the sections on chmod and chown to learn more.
Let's take a closer look at what the return of the "ls -l" command from earlier tells us.
The letters at the beginning of the line describe the permissions granted to the file. We can remember two things:
For example, for this line:
drwxr-xr-x 2 www daemon 512 May 5 17:10 bin
We see that it is a directory. Then we see three triplets of letters:
rwx: The owner "www" can:
r-x: Those belonging to the "daemon" group can:
r-x: All others can:
As a general rule, you should avoid giving write and execute rights to people other than the owner whereever you can. Sometimes, reading permission is also withdrawn on certain files (passwords, etc.).
To change permissions, there are several methods.
Some use a set of numbers, like "chmod 700". I find this way not very explicit when you are not used to it yet. You may prefer to use "chmod <identity>Β±<permission>" where:
Would you like a few examples?
These changes can be applied recursively (to everything below that folder) with the -R flag.
Tip: to allow moving in folders, without making the files executable, use X (uppercase) instead of x.
If you want to understand the numerical notation of a chmod:
There is no distinction between folders or files, so proceed with caution.
In the triplet passed to "chmod", the first digit represents the owner, the second the group, and the last the others.
For each digit of this triplet, we add the values that "r", "w" and "x" stand for. This means that chmod 700 grants "rwx" permissions to the owner, and none to the group and others (7 = 4 + 2 + 1).
Finally, in order to define the permissions by distinguishing between the folder and the files, and not to make a file executable with a "chmod -R" (recursive), the "find" command is your friend:
# For folders: find . -type d -exec chmod 755 {} \; # For files: find . -type f -exec chmod 644 {} \;
As always, the "man chmod" will tell you more.
Each file has an owner and is part of a group. This will allow us to give certain permissions to the owners, which will not necessarily be the same as those given to the group member.
To modify the owner and the group, we use the chown command.
# chown <owner>:<group> filename
Before we talk about how to handle files, let's look at some shorthand.
With pwd you ask "where am I?" πΊοΈ
$ mkdir name_of_new_folder
Use the -p flag to create a whole structure in one shot:
$ mkdir -p ~/folder/with/some/subfolders
To move to the /var/www folder:
$ cd /var/www
The cd command without argument moves you to your $HOME.
To copy a file:
$ cp source_file copy_file
To copy a folder and its contents:
$ cp -R source_folder copy_folder
rm means "remove".
$ rm path_to_the_folder $ rm -R path_to_the_folder
$ mv source destination
This works like cut and paste.
To only view a file, use the "less" command.
Then you can search for any string of characters by pressing / and entering your search. Press n to go to the next occurrence, or N to go back.
To exit less, press q.
This command will come in handy if you want to search through the content of your logs π.
Here is the real reason why there aren't many support forums for OpenBSD but only a mailing list: the man pages are very comprehensive, complete, with examples, and most of the time are sufficient to answer questions/problems encountered.
The man command display a man page.
Note that there are different sections for categorizing man pages:
Also, it sometimes happens that a man page exists in several different sections: its content is not the same. In order to differenciate them, one refers to a manpage as follows: "page_name(section)".
For example: "apm(8)", or "apm(4)". Or "man(1)" and "man(7)". Yes, man has a "man" page.
We use this command as follows, without parenthesis:
$ man (section) page
The section is optional.
To practice, run "man hier". Use arrows to scroll. As with "less", you can search with /. Notice the "SEE ALSO" part which invites you to read other manpages that may be of interest. Exit with q.
If you don't know what the name of the man page is, you can search for it with the "apropos" command:
$ apropos search_term
Knowing how to edit a file is crucial.
There are a lot of text editors (vim, nano ...).
vi The default editor on OpenBSD is vi. (There is ed too...)
https://man.openbsd.org/man/vi
It may be confusing to use at first, so some people may want to install another editor instead. However, vi is handy once you get it. If, on the contrary, you are already used to the emacs editor, you will find what you are looking for with the mg editor, also available by default.
Here are some tips for using vi through an example. To edit the /etc/iloverocknroll file, you would enter this:
$ vi /etc/iloverocknroll
The contents of this file will then show up.
Most of the time, you will only do this:
Are you still here ? π
So let's go a little further (but not too much, we promise π). Take note that there are three modes:
To save the changes, press ":" then "w" (write). Confirm with Enter. We can now quit by writing ":q". Note that you can go faster by typing directly ":wq".
To cancel a modification press "u". To remove changes again, press "u" then "." as many times as necessary. "." repeat the last action. To redo an action you undid previously, use "ctrl-R""
In order to search for a string, which is very useful in large files, press the / key and enter a search term.
If you want to exit without saving your changes then enter: "q!".
Other very handy tips:
In order to activate/deactivate daemons, the rcctl command is provided for this purpose. All available services are in the /etc/rc.d folder. Here is a short overview:
If you prefer the manual method, then you can directly edit the /etc/rc.conf.local file which manages the services launched at startup.
Let's practice with a little exercise. Follow the instructions below, then check if you got same thing as in the "Answer". Try to do it from memory first. If you get stuck, read the page again and look for what you are missing.
The answer:
$ cd /tmp $ mkdir ah $ cd ah $ vi dw.txt $ cp dw.txt DrWho.txt $ chmod 600 DrWho.txt $ rm dw.txt $ cd ~ $ pwd /home/prx $ ls -l /tmp/ah total 2 -rw------- 1 prx wheel 22 May 5 21:10 DrWho.txt $ cat /tmp/DrWho.txt Allons-y
Note that we can replace "cd ~" by "cd $HOME", or even by "cd".
First, read afterboot(8) and intro(8) manpages. Believe it or not, OpenBSD's developpers wrote a few words for you after install π.
$ man afterboot $ man intro
You'll learn how to read manpages actually.
See examples in /etc/examples.
If you add ports, read included instructions un /usr/local/share/doc/pkg-readmes when pkg_add notice about such file.
Edit /etc/mail/aliases and set root's mail address to get important reports:
root: batman@athome.tld
You may want to disable unused daemons, such as sndiod in charge of audio (unless you need it of course).
By the way, let's talk about rcctl to deal with daemons.
List enabled daemons:
# rcctl ls on
To stop daemon, i.e audio server:
# rcctl stop sndiod
And to disable daemon for next boot:
# rcctl disable sndiod
You probably want to enable power management. As an example, below lines will enable apmd, add "-A" flag to daemon startup and actually start apmd:
# rcctl enable apmd # rcctl set apmd flags -A # rcctl start apmd
Read intro(8) to learn about default daemons availables on OpenBSD:
man 8 intro
IP means Internet Protocol. But first, let's be serious for a minute and talk about Santa π .
To send a letter asking for all the presents you want, you write to the famous address "Santa Claus, North Pole, Rainbow road.". But how does Santa knows where to answer? Of course you wrote your own address on the back of the envelope.
That's how computers and servers work: you know where is the video you want to watch, and the server hosting the video knows where to send data.
Every device has its own IP on the internet. There are numbers like 192.0.2.2, not as good looking as Santa's pretty address isn't it?
How devices knows what is the IP of domain name like wikipedia.org ? It there a directory?
Indeed there is something like that: DNS. We'll talk about it later.
There are differences between local (or private) IP ans public IP. Most of the time, to reach the internet, your ISP lend you a router so your network look like this:
+-----------------------+ | | | Local Network (home) | | PRIVATE IP | | | | | | laptop <---+------+ | 192.168.1.20 | | | | | | | | | Phone <---+--+ ++---------------+ | 192.169.1.21 | | | | | | +--+ Router (box) | +----------+ | | | |<---+ INTERNET | | Computer <---+-----+ PUBLIC IP: | +----------+ | 192.168.1.22 | | 192.0.2.2 | | | +--+ | | * * * * * * * * * | | ++---------------+ | * Your server <---+--+ | | * 192.168.1.23 * | | | * * * * * * * * * | | | | | | Game console <--+------+ | 192.168.1.24 | | | +-----------------------+
To host a server, it is useful to have a static IP delivered by your ISP. Some don't, so you may want to look for a VPN or dynamic DNS or change ISP π
To run your own server, you must know what are its IP, public, local, and its gateway (router). At first, one may want to configure its network using dhcp then configure a static network when more confident.
Let's see a few words to do so.
First, understand your server is probably behind a router given by your ISP. The router received a public IP. People "on the internet" can reach this IP.
The router allocate private addresses to devices connected in your local network. Each device has its own private IP: one for your phone, another for a printer, a computer, a console... They all share one public address.
Private addresses can be in three ranges:
Your private or local IP is the one your computer use, the one it knows.
To find your local IP, run "ifconfig" and search for "inet". You'll see something like that:
# ifconfig |grep inet inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x3 inet 127.0.0.1 netmask 0xff000000 inet 192.168.1.2 netmask 0xffffff00 broadcast 192.168.1.255 inet6 fe80::feaa:14ff:fe65:5f86%re0 prefixlen 64 scopeid 0x1
inet means IPV4, inet6 means IPv6.
Your public address is the one "used" when you browse the web. Websites you're used to read see this IP. If you don't know it, you can check one of these links (amongst many others):
https://lehollandaisvolant.net/tout/ip
The router is the box your ISP gave you. We also call it a gateway because on a side there is the "public" network, on the other your "private network". The router deals with redirections: if someone wants to reach your website, the router will lead him to your server's private address.
To find your gateway IP, use "route" command:
# route -n show Routing tables Internet: Destination Gateway Flags Refs Use Mtu Prio Iface default 192.168.1.1 UGS 35 4827 - 8 re0 224/4 127.0.0.1 URS 0 13 32768 8 lo0 127/8 127.0.0.1 UGRS 0 0 32768 8 lo0 127.0.0.1 127.0.0.1 UHhl 9 969 32768 1 lo0 ...
The first line is what you're looking for: 192.168.1.1 in this example.
Every device in your network has a name to identify it. It is the hostname.
On a computer, you can change this name. To do so on OpenBSD, edit the /etc/myname file and write the complete hostname:
server.athome.tld
To configure a network interface, you can use DHCP to autmatically get a local address. Be careful though, the "D" means "Dynamic", so this addres might change in the future depending on your router. Don't worry, in the next part, we'll see how to set up aliases to fix this.
To do so, edit /etc/hostname.if file, and replace ".if" by the name of your interface (run "ifconfig" to find it) and just write "autoconf" inside.
autoconf up
A bit more complicated, static configuration gives you more control and can complete dhcp.
In /etc/hostname.if (replace "if" with your interface name):
inet 192.168.1.2 255.255.255.0 192.168.1.255 inet alias 192.168.1.9 255.255.255.0 192.168.1.255 # and as many as you want # inet (alias) local_ip network_mask broadcast_add up
If you're not sure for netmask and broadcast, at first configure using dhcp and look at the output of ifconfig.
If you don't have dhcp set up, you must specify the route to your gateway. To do so, you can edit /etc/mygate file or add a "!route" command to /etc/hostname.if. I prefer the latter as it avoid to split configuration in multiple places.
The gateway is you router's IP: 192.168.1.1 here.
inet 192.168.1.2 255.255.255.0 192.168.1.255 inet alias 192.168.1.9 255.255.255.0 192.168.1.255 !route add -inet default 192.168.1.1 up
See also "man hostname.if":
https://man.openbsd.org/hostname.if
IPv6 is the new protocol to use facing the lack of ipv4 available. The main advantage is that you don't need a router doing NAT: your machine is directly reachable.
To configure your interface, magic happens in /etc/hostname.if with the "inet6" lines:
inet... inet6 2001:db8:1:1::2 64 # adress inet6 autoconf # SLAAC, if you want !route add -inet6 default 2001:db8::1 up
You can mix inet and inet6 instructions.
To keep things easy and stay lazy, I suggest to ask the router for automatic configuration and add aliases for public ips to reach your server:
inet autoconf inet6 autoconf inet alias 192.0.2.2 255.255.255.0 192.0.2.255 inet6 alias 2001:db8::2 64 up
Most of your devices access the Internet through a router, probably given by your ISP. The router has a public IP address, making it reachable from the outside. We must learn how to tell the router to forward requests from the outide to your server (not anything else) depending which port number is used.
You can imagine your router as a big wall when seen from the outside. In this wall, there are doors: we call them "ports". When someone knocks at the door 80, he want to see a web server. Your router has a configuration line for this case and will redirect the visitor to your server internal IP, not to your smartphone.
Most of the doors will remain closed, because you didn't configure a redirection for them, and that's fine to keep your other equipments safe.
+---------------+ | | | Router (box) | | *********** | | | +--------+-- door 443 | +---------+ | | | | |<--+ | | | Server | ?<-+---door 143 <-+--- [Evil bot πΏ] | |<--+ | | +---------+ | | | ^ +--------+-- door 80 <--+--- [Guest πΌ] | | | | | | +-------------+-- door 22 | | | +---------------+
Your router is a GATEWAY with a janitor.
Understand that if your server is reachable with IPV6, no redirection is required: its IPV6 is routable and reachable. That's why it is important to always configure the firewall on your server too.
To configure your router, it might have a web interface reachable using a browser from a computer connected on your local network. Some ISP provide a configuration tool on their web panel. It depends, you'll have to find out or ask your ISP how their router work.
Most of the time, you can try these URI in a browser:
Probably, a username/password will be required. Ask your ISP, or try "admin/admin" or "admin/password", or look what's written on the router.
Here are more clues.
https://www.wikihow.com/Configure-a-Router
If you do not want to bother with redirectionc, configure a DMZ to your server on your router: all traffic will be redirected to your server. If so, remember to configure your firewall accordingly π.
Instead of writing your public IP, someone might want to reach your server using something more human friendly: a domain name.
What is a domain name ?
One can register a domain, i.e. "something-cool.tld" as a sign pointing to your IP address. When an human enter "something-cool.tld", the computer will ask the registrar what IP is behind this sign to reach it. In this case, the domain is resolved.
It is easier to remember, it gives identity to your project, and it let you organise it using subdomains (webmail.athome.tld, cloud.athome.tld...).
Below is a little comic to explain a DNS query:
https://wizardzines.com/comics/life-of-a-dns-query/
You can find free registrar, or rent a domain name. There are many registrars out there. As examples:
When a device try to reach "athome.tld", it ask a DNS resolver what IP is behind. DNS is like road signs.
To create this sign, you must link the domain name to your IP in a zone. It can be done in registrar panel if you don't host your own domain name server (see nsd later π). As example:
athome.tld A 192.0.2.2
Different records exists. You must at least know:
blog.athome.tld CNAME athome.tld wiki.athome.tld CNAME athome.tld webmail.athome.tld CNAME athome.tld
Learn more with these links:
https://en.wikipedia.org/wiki/Domain_Name_System