Run Your Own Server
Configuring your own box on the Internet is a lot of fun, and provides an opportunity to experiment with Internet services in general.
| Service | Cost | Provider |
| Domain registration | $11/yr. | name.com |
| OpenBSD VPS hosting | $9/mo. | bsdvm.com |
| Secondary DNS | $10/yr donation | buddyns.com |
VPS Hosting
Initial Setup
Getting started with a service like bsdvm.com is easy, after you select a plan and enter your data an e-mail will be sent with your initial login information. First login and change your login credentials.
ssh sshadmin@65.49.80.28
useradd -m eradman vi /etc/group userdel sshadmin rm -rf /home/sshadmin
Out of the gate you may also want to prevent password authentication for anyone not in the weel group.
# Require keys for regular users Match Group !wheel PasswordAuthentication no
Then set the hostname and timezone
echo "vm.eradman.com" > /etc/myname ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime
Partition Layout
Entry-level VPS plans may only have 5GB of disk. Since I'm running a web server don't need a lot of space for /usr and /home, so I'll move things about so that ample storage for logs and www content. This is the initial layout
Filesystem Size Used Avail Capacity Mounted on /dev/sd0a 938M 46.8M 844M 5% / /dev/sd0e 817M 16.0K 776M 0% /home /dev/sd0d 2.9G 534M 2.3G 19% /usr
First I'll move everything from /usr to the partition presently used for /home
cd /home dump 0af - /usr | restore rf -
Then edit /etc/fstab to reflect the new location of /usr
cd /etc/ sed -e 's:^/dev/wd0e:#/dev/wd0d:' -e 's:^/dev/wd0d:/dev/wd0e:' fstab > fstab.new mv fstab.new fstab reboot
Now the partition layout should now look like this
Filesystem Size Used Avail Capacity Mounted on /dev/sd0a 938M 46.9M 844M 5% / /dev/sd0e 817M 536M 240M 69% /usr
Now make the new /var partition, and move /var into it. If UUIDs are used instead of driver letters like rwd0d might look like 877b52f265379d61.d .
newfs /dev/rwd0d mkdir /mnt/var mount /dev/wd0d /mnt/var cd /mnt/var dump 0af - / | restore rf - ls | grep -v var | xargs rm -r mv var/* . rmdir var echo "/dev/wd0d /var ffs rw,nodev,nosuid 1 2" >> /etc/fstab rm /var/log/*.gz reboot
Optionally, free up some space
rm -r /usr/X11R6
rm -r /etc/X11
rm -r /usr/games
find /usr/share/man -type f -name *.[1-9] -exec rm {} \;
/usr/libexec/locate.updatedb
The final partition layout now looks something like this; plenty of space for log messages and www content.
Filesystem Size Used Avail Capacity Mounted on /dev/sd0a 938M 45.8M 845M 5% / /dev/sd0d 2.9G 7.7M 2.8G 0% /var adev/sd0e 817M 536M 240M 69% /usr
Now is a good time to disable root logins
#/etc/sshd/sshd_config PermitRootLogin no
Services - HTTP
chown eradman:users /var/www/htdocs rm /var/www/htdocs/*
Nginx
If you like Nginx that's easy as well
http { access_log /var/www/logs/access.log main; sendfileon; gzip on; index index.html; server { server_name eradman.com www.eradman.com; root/var/www/htdocs/eradman.com; location /posts { autoindex on; } } }
Nginx provides an easy way to exclude some content from it's web logs which saves on a lot of space an noise.
server { ... location ~* \.(css|png|js|ico)$ { access_log off; expires max; } }
Services - DNS
Primary Nameserver
echo 'named_flags=""' >> /etc/rc.conf.local
#/var/named/etc/named.conf zone "eradman.com" { type master; file "master/eradman.com"; };
;/var/named/master/eradman.com $ORIGIN eradman.com. $TTL 6h @IN SOA vm.eradman.com. hostmaster.eradman.com. ( 2 ; serial 1h ; refresh 30m ; retry 7d ; expiration 1h ) ; minimum NS vm.eradman.com. A 65.49.80.28 www IN CNAME eradman.com. vm IN CNAME eradman.com.
After restarting named verify like so
$ host eradman.com eradman.com has address 65.49.80.28 eradman.com mail is handled by 50 mail.freeshell.org.
Secondary Nameservers
There are two rules to running your own nameserver
- There must be at least two
- They must not have the same IP address
All registrars that I'm aware have an awkward JavaScript-only user interface, but I recommend name.com because they provide very quick e-mail support.
This is why a secondary nameservice is required , and buddyns.com provides an excellent solution. Once you create an account update your nameserver config to answer client queries so that they can keep the nameservers in sync.
#/var/named/etc/named.conf options { allow-transfer { 173.244.206.26; # a.transfer.buddyns.com 88.198.106.11; # b.transfer.buddyns.com }; }
Next add them as secondary authority for each zone file.
;/var/named/master/eradman.com NS b.ns.buddyns.com. NS d.ns.buddyns.com.
Once this works locally, use a DNS health check such as intodns.com to verify that your configuration is correct.
First write your hosting provider and ask them to add a PTR record for your IP address, then add an MX record for your domain
$ORIGIN entrproject.org. MX 50 vm.eradman.com.
Then stop sendmail and enable smtpd by following the instructions in the smtpd(8) man page.
Confirm that local relays are working by tailing /var/log/maillog or by running smtpd in the foreground with -dv
Now proceed to create rules in /etc/mail/smtpd.conf for virtual domains and SMTP relay
home_network = "74.65.88.110" listen on lo0 listen on egress port 25 listen on egress port 587 tls certificate vm.eradman.com enable auth map "aliases" { source db "/etc/mail/aliases.db" } accept for local alias aliases deliver to mbox accept from $home_network for all relay accept from local for all relay
OpenSMTPd supports SSL/TLS and STARTTLS modes using the keyword https (normally port 465), and tls (normally port 587). Both of these protocols are SSL connections, but the latter switches to secure mode after connecting. If the client sends a username and password the connection is considered local and passes the last rule, allowing relay. The smtpd.conf(5) mage page suggests a means of generating your own certificate.
Mapping virtual users is as easy as defining a map and then adding a delivery rule
echo "eradman@entrproject.org eradman" >> /etc/mail/virtual echo "ericshane@eradman.com eradman" >> /etc/mail/virtual makemap /etc/mail/virtual
Then add a filter to smtpd.conf using the new hash
map "virtual" { source db "/etc/mail/virtual.db" }
accept from all for domain "entrproject.org" alias "virtual" deliver to mbox
accept from all for domain "eradman.com" alias "virtual" deliver to mbox
Other computers that are permitted to relay mail can simply add a relay via rule to their smtpd configuration
accept for any relay via "smtp://vm.eradman.com"
What next? Now that you have e-mail running, you can use the sendbug(1) utility to submit a PR!
Mail Retrieval over SSL
Nginx includes a very nice set of proxy modules for common mail protocols that provides a very nice mans of proving an SSL-gateway to simple clear-text protocols such as pop3d. These modules are not compiled in the Nginx base install, but they are enabled if you install Nginx from ports. The following addition to nginx.conf will enable the pop3s to pop proxy:
mail { server_name vm.eradman.com; auth_http localhost:9000; proxy on; ssl_protocols TLSv1 SSLv3; ssl_certificate /etc/mail/certs/vm.eradman.com.crt; ssl_certificate_key /etc/mail/certs/vm.eradman.com.key; pop3_auth plain apop cram-md5; server { protocol pop3; listen 995; ssl on; pop3_auth plain; } }
While debugging the following line may also prove useful information
error_log /var/log/nginx-error.log info;
The only manual assembly required is to establish a mechanism for auth_http to use. Nginx will issue an HTTP GET to this service to request the parameters for the backend connection. Unfortunately Nginx doesn't have CGI support, so I resorted to writing a short script to be launched by inetd
#!/bin/sh # mailauth - Nginx mail director for inetd server=127.0.0.1 while read header do line="$(echo $header | tr -d '\r')" case $line in "Auth-Protocol: pop3") port=110;; "Auth-Protocol: imap") port=143;; "Auth-Protocol: smtp") port=25;; "") break esac done print "HTTP/1.1 200 OK\r" print "Content-type: text/plain\r" print "Auth-Status: OK\r" print "Auth-Server: ${server}\r" print "Auth-Port: ${port}\r" print "\r" echo OK
This shell script returns 127.0.0.1 as the authentication server and a port number appropriate for each local service. Run it from inetd by making the following config changes
# /etc/services mailauth 9000/tcp # nginx mail proxy
# /etc/inetd.conf pop3 stream tcp nowait root /usr/sbin/popa3d popa3d mailauth stream tcp nowait root /var/www/cgi-bin/mailauth mailauth
Backups
Now that everything is in working order set up a small script to make a copy of each file system.
#/bin/sh host=eradman@backups.eradman.com df -h /sbin/dump -0af - /home | ssh $host "cat > /vm/eradman.com/home.dump" /sbin/dump -0af - /var | ssh $host "cat > /vm/eradman.com/var.dump" /sbin/dump -0af - / | ssh $host "cat > /vm/eradman.com/root.dump"
See also Why's and When's of Backup and Restore by Gerhard Mourani for more information about backup levels and rotation.