The Golem multi-function server
This document describes how to build Golem, a multi-function server. Golem runs on commodity router hardware and provides a number of features:
- SSH access
- a media service compatible with iTunes
- a file share
- an LDAP and Kerberos service
- a network proxy
We build Golem on top of OpenWrt because of the distribution's simplicity and small size. Golem is made up of roughly 120 packages, and its programs and configurations take up less than 50 MB of storage space. Here we assume that Golem will run within the confines of a Xen hypervisor.
Establish the Golem VM
Perform the following steps on the Xen Dom0 host to establish the VM which will host Golem:
- Obtain the x86_64 OpenWrt image at https://downloads.lede-project.org/releases/17.01.1/targets/x86/64/lede-17.01.1-x86-64-combined-ext4.img.gz.
- Uncompress the image and place it at /var/lib/xen/images/golem-lede-17.01.1-x86-64-combined-ext4.img on the Xen Dom0 host.
- Create a disk image to serve as the server's large data store (see our notes on platform virtualization) and name it /var/lib/xen/images/golem-data.qcow.
- Write the following at /etc/xen/vm-golem.cfg on the Xen Dom0 host (replace XX:XX:XX:XX:XX:XX):
name = "golem" memory = 1024 vcpus = 1 builder = "hvm" vif = [ "model=e1000,script=vif-bridge,bridge=xenbr0,mac=XX:XX:XX:XX:XX:XX" ] disk = [ "tap2:tapdisk:aio:/var/lib/xen/images/golem-lede-17.01.1-x86-64-combined-ext4.img,xvda,w", "tap2:qcow:/var/lib/xen/images/golem-data.qcow,xvdb,w" ] serial = "pty"
Software installation
Perform the following steps on Golem:
- Set the root password: passwd.
- Remove unnecessary packages:
opkg remove \ dnsmasq \ kmod-ppp \ kmod-pppoe \ kmod-pppox \ kmod-r8169 \ logd \ luci \ luci-app-firewall \ luci-base \ luci-lib-ip \ luci-lib-nixio \ luci-proto-ipv6 \ luci-proto-ppp \ luci-theme-bootstrap \ mtd \ odhcpd \ ppp \ ppp-mod-pppoe \ r8169-firmware \ uhttpd-mod-ubus \ uhttpd
- Configure networking by writing /etc/config/network:
config interface loopback option ifname lo option proto static option ipaddr 127.0.0.1 option netmask 255.0.0.0 config interface lan option ifname eth0 option proto dhcp
- Install the necessary software:
opkg update opkg install \ block-mount \ ca-certificates \ dmapd \ freifunk-watchdog \ gst1-mod-app \ gst1-mod-audioconvert \ gst1-mod-audioparsers \ gst1-mod-flac \ gst1-mod-gio \ gst1-mod-id3demux \ gst1-mod-lame \ gst1-mod-mpeg2dec \ gst1-mod-mpg123 \ gst1-mod-ogg \ gst1-mod-playback \ gst1-mod-theora \ gst1-mod-typefindfunctions \ gst1-mod-vorbis \ krb5-server \ nfs-kernel-server \ ntpd \ openldap-server \ rsync \ syslog-ng \ tinyproxy \ zoneinfo-core \ zoneinfo-northamerica
- Install a public SSH key at /etc/dropbear/authorized_keys.
Configuring Kerberos authentication
- /etc/krb5.conf (replace EXAMPLE.COM):
[libdefaults] default_realm = EXAMPLE.COM dns_lookup_realm = false dns_lookup_kdc = false ticket_lifetime = 24h forwardable = yes [realms] EXAMPLE.COM = { kdc = localhost:88 admin_server = localhost:749 default_domain = local } [domain_realm] .local = EXAMPLE.COM local = EXAMPLE.COM
- Add Kerberos principals by running kadmin.local and then add_principal user for each user.
Configuring LDAP network information
- /etc/openldap/example.com.cert: Place your certificate in /etc/openldap/example.com.cert.
- /etc/openldap/example.com.key: Place your private key in /etc/openldap/example.com.key.
- /etc/openldap/ca.cert: Place your CA certificate in /etc/openldap/ca.cert.
- /etc/openldap/slapd.conf (replace PASSWORD and example.com):
include /etc/openldap/schema/core.schema include /etc/openldap/schema/cosine.schema include /etc/openldap/schema/inetorgperson.schema include /etc/openldap/schema/nis.schema include /etc/openldap/schema/autofs.schema include /etc/openldap/schema/sudoers.schema allow bind_v2 TLSCACertificateFile /etc/openldap/ca.cert TLSCertificateFile /etc/openldap/example.com.cert TLSCertificateKeyFile /etc/openldap/example.com.key pidfile /var/run/slapd.pid argsfile /var/run/slapd.args database ldif directory /etc/openldap/db suffix "dc=example,dc=com" rootdn "cn=Manager,dc=example,dc=com" rootpw PASSWORD
- /etc/openldap/schema/sudoers.schema:
attributetype ( 1.3.6.1.4.1.15953.9.1.1 NAME 'sudoUser' DESC 'User(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) attributetype ( 1.3.6.1.4.1.15953.9.1.2 NAME 'sudoHost' DESC 'Host(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) attributetype ( 1.3.6.1.4.1.15953.9.1.3 NAME 'sudoCommand' DESC 'Command(s) to be executed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) attributetype ( 1.3.6.1.4.1.15953.9.1.4 NAME 'sudoRunAs' DESC 'User(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) attributetype ( 1.3.6.1.4.1.15953.9.1.5 NAME 'sudoOption' DESC 'Options(s) followed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) attributetype ( 1.3.6.1.4.1.15953.9.1.6 NAME 'sudoRunAsUser' DESC 'User(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) attributetype ( 1.3.6.1.4.1.15953.9.1.7 NAME 'sudoRunAsGroup' DESC 'Group(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) attributetype ( 1.3.6.1.4.1.15953.9.1.8 NAME 'sudoNotBefore' DESC 'Start of time interval for which the entry is valid' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 ) attributetype ( 1.3.6.1.4.1.15953.9.1.9 NAME 'sudoNotAfter' DESC 'End of time interval for which the entry is valid' EQUALITY generalizedTimeMatch ORDERING generalizedTimeOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 ) attributeTypes ( 1.3.6.1.4.1.15953.9.1.10 NAME 'sudoOrder' DESC 'an integer to order the sudoRole entries' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ) objectclass ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' SUP top STRUCTURAL DESC 'Sudoer Entries' MUST ( cn ) MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ sudoRunAsGroup $ sudoOption $ sudoNotBefore $ sudoNotAfter $ sudoOrder $ description ) )
- From a computer with ldapadd on golem's network, execute ldapadd -x -D "cn=Manager,dc=example,dc=com" -W -f accounts.ldif, where accounts.ldif contains records like (replace example, com, user, and Some User):
dn: dc=example,dc=com objectClass: organization objectClass: dcObject o: Example Organization dc: example dn: automountMapName=auto_master,dc=example,dc=com objectClass: top objectClass: automountMap automountMapName: auto_master dn: automountMapName=auto_root,dc=example,dc=com objectClass: top objectClass: automountMap automountMapName: auto_root dn: automountKey=/-,automountMapName=auto_master,dc=example,dc=com objectClass: top objectClass: automount automountKey: /- automountInformation: auto_root dn: automountKey=/home,automountMapName=auto_root,dc=example,dc=com objectClass: top objectClass: automount automountKey: /home automountInformation: golem.example.com:/home/ dn: ou=group,dc=example,dc=com objectClass: organizationalUnit ou: group dn: cn=ldapusers,ou=group,dc=example,dc=com objectClass: posixGroup objectClass: top cn: ldapusers userPassword:: WFhYWA== gidNumber: 1002 dn: ou=people,dc=example,dc=com objectClass: organizationalUnit ou: people dn: uid=user,ou=people,dc=example,dc=com uid: user cn: Some User objectClass: account objectClass: posixAccount objectClass: top userPassword:: WFhYWA== loginShell: /bin/bash uidNumber: 1102 gidNumber: 1002 homeDirectory: /home/user gecos: Some User dn: ou=sudoers,dc=example,dc=com objectClass: top objectClass: organizationalUnit ou: sudoers dn: cn=user,ou=sudoers,dc=example,dc=com objectClass: top objectClass: sudoRole cn: user sudoUser: user sudoHost: ALL sudoCommand: ALL
Configuring the dmapd media server
- /etc/dmapd.conf:
[General] Database-Dir=/mnt/sda1/var/dmapd [Music] Type=DAAP Dirs=/mnt/sda1/Storage/Music/ Transcode-Mimetype=audio/mp3 [Picture] Type=DPAP Dirs=/mnt/sda1/Storage/Pictures/
Configuring NFS
- /etc/exports:
/mnt/sda1 *(fsid=root,rw,insecure,no_subtree_check,async) /mnt/sda1/Storage *(rw,insecure,no_subtree_check,async) /mnt/sda1/home *(rw,insecure,no_subtree_check,async)
Configuring Tinyproxy
- /etc/tinyproxy-filter.conf: List the websites that you want tinyproxy to allow access to, one per line (e.g., www.example.com).
Configure the firewall
- /etc/config/firewall:
config defaults option drop_invalid 1 option input ACCEPT option output ACCEPT option forward ACCEPT config zone option name lan option network lan option input ACCEPT option output ACCEPT option forward DROP
Configure basic system settings
- /etc/config/fstab:
config global automount option from_fstab 1 option anon_mount 1 config global autoswap option from_fstab 1 option anon_swap 1
- /etc/config/system:
config system option hostname golem.example.com option timezone EST5EDT,M3.2.0,M11.1.0 config timeserver ntp list server 0.openwrt.pool.ntp.org list server 1.openwrt.pool.ntp.org list server 2.openwrt.pool.ntp.org list server 3.openwrt.pool.ntp.org option enabled 1 option enable_server 0
- /etc/config/tinyproxy:
config tinyproxy option enable 1 option User nobody option Group nogroup option Port 8080 option Timeout 600 option SysLog 1 option LogLevel Info option MaxClients 100 option MinSpareServers 1 option MaxSpareServers 3 option StartServers 1 option MaxRequestsPerChild 0 option ViaProxyName "tinyproxy" option Filter "/etc/tinyproxy-filter.conf" option FilterDefaultDeny 1
- /etc/config/freifunk-watchdog:
config process option process dropbear option initscript /etc/init.d/dropbear config process option process crond option initscript '/etc/init.d/cron' config process option process dmapd option initscript /etc/init.d/dmapd config process option process krb5kdc option initscript /etc/init.d/krb5kdc config process option process slapd option initscript /etc/init.d/ldap config process option process rpc.statd option initscript /etc/init.d/nfsd config process option process rpc.mountd option initscript /etc/init.d/nfsd config process option process ntpd option initscript /etc/init.d/ntpd config process option process portmap option initscript /etc/init.d/portmap
- /etc/config/network:
config interface loopback option ifname lo option proto static option ipaddr 127.0.0.1 option netmask 255.0.0.0 config interface lan option ifname eth0 option proto dhcp
- /etc/config/dropbear:
config dropbear option PasswordAuth 'off' option RootPasswordAuth 'off' option Port '22'