HON’s Wiki # Linux Server Applications

Home / Linux Servers

Contents

If not stated then the instructions are for Debian. Some may be for CentOS (5?) and extremely outdated. Some applications may be located in different sections/pages on this wiki.

Apache

Outdated

Setup

  1. Install: apt install apache2
  2. Update security.conf:
     ServerTokens Prod
     ServerSignature Off
    

Usage

Apticron

Sends an emails when APT updates are available.

Setup

  1. Prerequesites:
    • Setup Postfix or similar so the system can actually send mail.
    • Make sure the root email alias is set appropriately.
  2. Install: apt install apticron
  3. Setup the config: /etc/apticron/apticron.conf
    • Create it: cp /usr/lib/apticron/apticron.conf /etc/apticron/apticron.conf
    • The defaults are typically fine.
  4. Modify the check interval in /etc/cron.d/apticron (e.g. 30 23 * * *).
  5. Fix a bug causing it to ignore IPADDRESSNUM and always print all IP adresses:
    1. Open /usr/sbin/apticron.
    2. Find this line: IPADDRESSES=`(echo $( /bin/hostname --all-ip-addresses ) ;
    3. Change it to: IPADDRESSES=`(
  6. Test it: apticron

Avahi Daemon

TODO

Setup

  1. Install: apt install avahi-daemon

AWS CLI

Possibly outdated

Setup

Usage

BIND

Info

Config

Usage

Config

Zones

Validation

Miscellanea

VaultWarden (Formerly bitwarden_rs)

A free community backend for Bitwarden.

TODO

Ceph

See Storage: Ceph.

Certbot

Setup

  1. Install: apt install certbot
  2. (Optional) Add post-update hook: In /etc/letsencrypt/cli.ini, add renew-hook = systemctl reload nginx or equivalent.

Usage

Chrony

An NTP client and server. By design more accurate than e.g. ntpd and systemd-timesyncd.

See NTP for more info about NTP.

Setup (Server)

  1. Install: apt install chrony
  2. Modify config (/etc/chrony/chrony.conf):
    • (Optional) Add individual servers: server <address> iburst
    • (Optional) Add pool of servers (a name resolving to multiple servers): pool <address> iburst
    • (Optional) Allow external clients: allow {all|<network>}
  3. Restart: systemctl restart chrony

Usage

DDNS

Cloudflare

Fail2ban

Setup

  1. Install fail2ban.
  2. Fix the firewall first so it configures itself correctly wrt. firewall blocking.
  3. Check the status with fail2ban-client status [sshd].

Google Authenticator

Possibly outdated

This setup requires pubkey plus MFA (if configured) plus password.

Setup

Home Assistant

See Home Assistant.

Intel SSD Data Center Tool (isdct)

See Storage: isdct.

ISC DHCP Server

Notes

Setup

  1. Install and enable isc-dhcp-server.
  2. Setup config files:
    • DHCPv4: /etc/dhcp/dhcpd.conf
    • DHCPv6 (optional): /etc/dhcp/dhcpd6.conf
  3. If using systemd-networkd, fix wrong startup order:
    • TODO

Configuration

lm_sensors

Get sensor values like temperature, voltage, fan speeds, etc.

Setup

  1. Install: apt install lm-sensors
  2. Test run it: sensors
  3. Run sensors-detect. When it asks, add the modules to /etc/modules.
  4. Load new modules: systemctl restart kmod
  5. Test run it: sensors

Troubleshooting

Linux PTP

Link: linuxptp.sourceforge.net

See PTP for more info about PTP.

Setup: Grandmaster Mode with Chrony Source (Debian)

Configure LinuxPTP as a GM using the default PTPv2 profile, with Chrony as the time source.

  1. Check if your NIC supports hardware timestamping: ethtool -T <interface>
    • Software mode is fine for testing stuff.
  2. Install:
    1. git clone --depth=1 --branch=v4.1 http://git.code.sf.net/p/linuxptp/code linuxptp
    2. cd linuxptp
    3. make
    4. sudo make install
    5. cd ..
  3. Copy the config file (default profile): cp linuxptp/configs/default.cfg /etc/ptp4l.conf
  4. Create the service config below, using the correct interface.
  5. Enable and start the service: sudo systemctl daemon-reload && sudo systemctl enable --now ptp4l.service
  6. Check the system journal to make sure it started correctly: sudo journalctl -u ptp4l.service -f
    • It should show “assuming the grand master role” after a few seconds, assuming it got the grandmaster role.
  7. Validate that PTP messages are sent: sudo tcpdump -nn -i <interface> host 224.0.1.129

Service config (/etc/systemd/system/ptp4l.service):

[Unit]
Description=LinuxPTP daemon
After=network.target

[Service]
ExecStart=ptp4l -4S -f /etc/ptp4l.conf -i eth0

[Install]
WantedBy=multi-user.target

MariaDB

A MySQL fork that is generally MySQL compatible.

Setup

  1. Install: apt install mariadb-server
  2. Run the initial configuration: mysql_secure_installation
    • Set a new MyriaDB root password.
    • Remove all anmonymous/test stuff.
    • Disallow remote root login.

Usage

NFS

The instructions below use NFSv4 without Kerberos. This should only be used on trusted networks and requires manual user and group ID management.

TODO

Subtree Checking

As a general guide, a home directory filesystem, which is normally exported at the root and may see lots of file renames, should be exported with subtree checking disabled. A filesystem which is mostly readonly, and at least doesn’t see many file renames (e.g. /usr or /var) and for which subdirectories may be exported, should probably be exported with subtree checks enabled.

Server (without Kerberos)

Setup

  1. (Recommended) Use NTP on both server and clients to make sure the clocks are synchronized.
  2. Install: apt install nfs-kernel-server
    • Install portmap if you need support for NFSv2 and v3 (not NFSv4).
  3. (Recommended) Enable only v4:
    1. In /etc/default/nfs-common, set:
         NEED_STATD="no"
         NEED_IDMAPD="yes"
      
    2. In /etc/default/nfs-kernel-server, set:
         RPCNFSDOPTS="-N 2 -N 3"
         RPCMOUNTDOPTS="--manage-gids -N 2 -N 3"
      
    3. Mask “rpcbind”:
         systemctl disable --now rpcbind.service
         systemctl mask rpcbind.service
         systemctl mask rpcbind.socket
      
    4. Restart it: systemctl restart nfs-server.service
    5. See which versions are running: cat /proc/fs/nfsd/versions (- means disabled)

Usage

  1. Setup a new directory contain all exports in:
    1. Create the root export containing other export dirs: mkdir /export
    2. Create the export mount dirs within the container.
    3. Mount the exports in the container using bind mounts.
      • Example fstab entry using ZFS: /zfspool/alpha /export/alpha none bind,defaults,nofail,x-systemd.requires=zfs-mount.service 0 0
    4. Remember to set appropriate permissions.
  2. Add filesystems to export in /etc/exports.
    • See the example config below.
    • For a list of options, see exports(5).
  3. Update the NFS table: exportfs -ra
    • Or, restart the service: systemctl restart nfs-server.service
  4. (Optional) Show exports: exportfs -v
  5. (Optional) Update the firewall:
    • NFSv4 uses only TCP port 2049.

Example /etc/exports:

# "fsid=root" is a special root export in NFSv4 where other exports are accessible relative to it.
# "sync" should generally always be used. While "async" gives better performance, it violates the spec and may cause data loss in case of power loss.
# "root_squash" maps client root users to an anon user to prevent remote root access. If that's desired, set "no_root_squash" instead.
# "no_subtree_check" disables subtree checking. Subtree checking may be appropriate for certain file systems, but in general it may cause more problems than it solves.
# "insecure" allows clients connecting from non-well-known ports.
/export/ *(fsid=root,ro,sync,root_squash,no_subtree_check,insecure)
/export/projects/ *(rw,sync,root_squash,no_subtree_check,insecure)

Client (without Kerberos)

Setup

  1. Install: apt install nfs-common

Usage

  1. Create a dir to mount the export to.
  2. (Optional) Try to mount it:
    • Command: mount -t nfs4 <server-hostname>:<export> <mountpoint>
    • Note that for NFSv4 with a root export, the export path is relative to the root export.
  3. (Optional) Make it permanent by adding it to fstab.
    • /etc/fstab entry: <nfs-server>:<export> <local-dir> nfs4 defaults 0 0

ntopng

Setup

  1. Install ntopng.
  2. Make sure service ntopng is enabled and running.
  3. Fix log dir owner: chown nobody:nogroup /var/log/ntopng
  4. Configure:
    1. Open /etc/ntopng.conf.
    2. Add -W=<new_port> to enable HTTPS.
    3. (Optional) Set -w=0 to disable HTTP.
  5. Restart it (takes a while).

ntpd

Note: I recommend Chrony instead of ntpd. It’s newer and by design more accurate.

Setup

  1. Disable systemd-timesyncd NTP client by disabling and stopping systemd-timesyncd.
  2. Install ntp.
  3. Configure servers/pool in /etc/ntp.conf, with the iburst option.
  4. Test with ntpq -pn (it may take a minute to synchronize).

Network UPS Tools (NUT)

Setup

Instructions for both primary nodes (netserver mode) and secondary nodes (netclient mode). Exclusive steps are marked “(Primary)” or “(Secondary)”. (Since “primary/secondary” was only recently introduced as a replacement, we’re using “master/slave” in the configs to avoid silent errors.)

  1. Install: apt install nut
    • The service will fail to start since NUT is not configured yet.
  2. Set the mode: Open /etc/nut/nut.conf and set MODE=netserver for primaries or MODE=netclient for secondaries.
  3. (Primary) Add the UPS(s): Open /etc/nut/ups.conf and add a declaration for all UPSes (see example below).
    • Try using the usbhid-ups driver if using USB. Otherwise, check the hardware compatibility list to find the correct driver. If the exact model isn’t there, try a similar one.
    • For usbhid-ups, see the example below and usbhid-ups(8).
    • You may need to modify some udev rules, but probably not.
  4. (Primary) Restart driver service: systemctl restart nut-driver.service
  5. (Primary) Set up local and remote access: Open /etc/nut/upsd.conf and set LISTEN :: 3493 and LISTEN 0.0.0.0 (unrestricted access).
    • To only listen on localhost instead, set LISTEN ::1 3493 and LISTEN 127.0.0.1.
    • Make sure the file is not world-readable.
    • Note that anonymous users (local or remote) have read-only access to everything, so you probably want to firewall this port.
  6. (Primary) Set up users: Open /etc/nut/upsd.users and add users (see example below).
    • Each client should have a separate user.
    • Make sure the file is not world-readable.
  7. (Primary) Restart the server service: systemctl restart nut-server.service
  8. Monitor the UPS: Open /etc/nut/upsmon.conf and add MONITOR <ups>@<host>[:<port>] <powervalue> <user> <password> <master|slave>.
    • Make sure the file is not world-readable.
    • powervalue is how many power supplies this system has which is supplied by the UPS. It’s used to calculate how many supplies are allowed to go offline. For single-PSU systems, use 1. For dual-PSU systems with both connected to this PSU, use 2. If this system is not powered by the UPS but you want to monitor it without shutting down when it goes critical, set it to 0.
  9. (Optional) Tweak upsmon:
    • Set RBWARNTIME (how often upsmon should complain about batteries needing replacement) to an appropriate value, e.g. 604800 (1 week).
  10. (Optional) Add a notify script to run for certain events:
    • In /etc/nut/upsmon.conf, add EXEC to all NOTIFYFLAG entries you want to run the script for (typically all except LOWBATT).
    • In /etc/nut/upsmon.conf, set the script to run using format NOTIFYCMD /opt/scripts/nut-notify.sh.
    • Create the executable script. See an example below for sending email (if Postfix is set up).
  11. Restart monitoring service: systemctl restart nut-monitor.service
  12. Check the logs to make sure nut-monitor successfully connected to the server.
    • Show systemd service log: journalctl -u nut-monitor.service
    • Note that upsc uses the driver directly, so it’s not useful for debugging the server or monitoring services.
  13. Configure delays:
    1. Figure out how much time is needed to shut down the master and all slaves, with some buffer time.
    2. Set the remaining runtime and remaining battery charge for when the UPS should send the “battery low” event (requires admin login): upsrw -s battery.runtime.low=<seconds> <ups> and upsrw -s battery.charge.low=<percent> <ups>
      • This may not work on all UPSes, even if the values appear to be modifiable. This means you’re probably stuck with the defaults.
      • TODO This resets when the driver or UPS is restarted, right?
    3. Set the delay from when the master issues the shutdown command to the UPS, to when the UPS powers off; and the delay from when the UPS receives power again to when it should turn on power: For usbhid-ups, this is set using offdelay and ondelay. Otherwise, it’s set using ups.delay.shutdown and ups.delay.start. The start delay must be greater than the stop delay.
      • The shutdown command is issued from the master after it’s done waiting for itself and slaves and is shutting itself down. The shutdown delay may be useful to increase if there are slaves that take much longer than the master to shut down.
    4. Restart the affected NUT services.
  14. Simulate a power loss, which should shutdown the secondaries, the primary and then the UPS after a delay: upsmon -c fsd

Example /etc/nut/ups.conf (uding usbhid-ups driver):

[alpha]
    desc = "PowerWalker VI 3000 RLE"
    # usbhid-ups should work for most UPSes with
    driver = usbhid-ups
    # Required but ignored by this driver
    port = auto
    # Sets "ups.delay.shutdown", the delay between the shutdown command and when the UPS powers off (default 20s)
    offdelay = 60
    # Sets "ups.delay.start", which has something to do with letting the UPS charge enough to make sure devices may fully boot (default 30s, must be greater than offdelay)
    ondelay = 120

Example /etc/nut/upsd.users:

[admin]
    password = <password>
    actions = set
    actions = fsd
    instcmds = all

[upsmon_local]
    password = <password>
    upsmon master

[upsmon_remote]
    password = <password>
    upsmon slave

(Notice the lack of = for upsmon.)

Example /etc/nut/upsmon.conf:

MONITOR alpha@localhost:3493 1 upsmon_local password1234 master
MINSUPPLIES 1
POLLFREQ 5
POLLFREQALERT 5
DEADTIME 20
HOSTSYNC 20
FINALDELAY 5
POWERDOWNFLAG /etc/killpower
NOTIFYCMD "/usr/bin/true"
SHUTDOWNCMD "/sbin/shutdown -h +0"
NOCOMMWARNTIME 3600
RBWARNTIME 604800

# See the original for NOTIFYMSG and NOTIFYFLAG examples.

Example notify script:

#!/bin/bash
echo -e "Time: $(date)\nMessage: $@" | mail -s "NUT: $@" root

Usage

Query the Server

Note: Anonymous users have read-only access to everything.

  1. Telnet into it: telnet localhost 3493
  2. Show UPSes: LIST UPS
  3. Show UPS vars: LIST VAR <ups>

OpenLDAP

Install Client

Usage

OpenSSL

Usage

Pi-hole (Docker)

Processor Counter Monitor (PCM)

Setup

  1. Load the MSR (x86 model-specific register) module: modprobe msr
    • Make this persistent or load it when you need PCM.
  2. Install the perf toolkit: apt install linux-tools-generic
  3. Download the source: git clone https://github.com/opcm/pcm
  4. Build it: make
    • The output binaries are contained in the current dir with .x suffixes.

Usage

CLI

GUI

Miscellanea

Portainer

Standalone Server Setup

Is typically run on a Docker host. Includes the agent.

  1. docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v ./data:/data portainer/portainer:<version>
    • Port 9000 is the web UI.
    • Port 8000 is an SSH tunnel server for communicating with agents.
  2. Open the web UI through port 9000 (by default) or a reverse proxy to configure it.
    • If /var/run/docker.sock was mounted, use “local”.

Standalone Agent Setup

Must be run on a Docker host. For extra Docker hosts you want to control with another Portainer server.

  1. docker run -d -p 9001:9001 --name portainer_agent --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/docker/volumes:/var/lib/docker/volumes portainer/agent:<version>
  2. TODO

Postfix

Setup (Satellite System)

References

Notes

Setup

  1. Install: postfix libsasl2-modules mailutils
    • If asked, choose to configure Postfix as a satellite system.
  2. Update the root alias:
    • In /etc/aliases, add root: [email protected] (to forward everything to [email protected]).
    • Run newaliases to update the alias DB file. (Optionally restart postfix.service to make it pick up the change instantly.)
  3. Update the main.cf config.
    • Example: main.cf
    • Update the hostname.
    • Only listen to localhost: Set inet_interfaces = loopback-only
    • Disable relaying: Set mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
    • Anonymize banner: smtpd_banner = $myhostname ESMTP
    • Use modern defaults: compatibility_level = 2
  4. Configure the relay provider:
    • See the references above.
    • SendGrid uses apikey as the username for API key access.
  5. Setup relay credentials (SASL):
    1. Create and secure credentials file: touch sasl_passwd && chmod 600 sasl_passwd
    2. Add your credentials using this format: [relay_domain]:port user@domain:password
    3. Update database: postmap sasl_passwd
  6. (Optional) Rewrite from-to fields: See below.
  7. Restart postfix.
  8. Try sending an email: echo "Test from $(hostname) at time $(date)." | mail -s "Test" root
Fancy To-From Fields

Use this mess to change the ugly From: [email protected] and To: [email protected] to From: "Node" <[email protected]> and To: "Admin" <[email protected]> when most/all email coming from the system is from root to some root alias.

  1. Add a smtp_header_checks file (arbitrary name).
  2. Add it to main.cf: smtp_header_checks = regexp:/etc/postfix/smtp_header_checks
  3. Test it locally: postmap -fq "From: root@$(hostname --fqdn)" regexp:smtp_header_checks
  4. Restart postfix.
  5. Test it with a real email.

Usage

Pterodactyl

General

Panel (Docker)

Setup

TODO

Logs are located in /app/storage/logs/laravel/ inside the container.

Daemon

  1. Follow the official guide.
  2. Install unzip.
  3. Setup a valid TLS certificate.
  4. Setup Docker DNS servers: Add { "dns": ["1.1.1.1", "1.0.0.1", "2606:4700:4700::1111", "2606:4700:4700::1001"] } to /etc/docker/daemon.json.

Game Servers

General

Counter-Strike: Global Offensive

See Counter-Strike: Global Offensive (CS:GO).

Team Fortress 2

See Team Fortress 2 (TF2).

Router Advertisement Daemon (radvd)

Setup

  1. Install and enable radvd.
  2. Setup config file: /etc/radvd.conf

Samba (CIFS)

Server

Setup

  1. Install: apt install samba
  2. Open TCP port 445 (and 139 if using NetBIOS).
  3. (Optional) Disable NetBIOS: systemctl disable --now nmbd and systemctl mask nmbd
  4. Configure it (see usage).

Configuration

Usage

Client

Setup

  1. Install: apt install cifs-utils
  2. Add permanent shares (see usage).

Usage and Configuration

smartmontools

NetSNMP

Debian: SNMP

Server

Installation

  1. Install: apt install snmpd
  2. TODO: Do we need human-readable names on the server? See the guide.
  3. Update the config:
  4. Enable and start: systemctl enable --now snmpd

SSHD

Security Recommendations

TFTP-HPA

Setup

  1. Install: apt install tftpd-hpa (note the d)
  2. (Optional) Configure it:
    • Config file: /etc/default/tftpd-hpa
    • Change dir: TFTP_DIRECTORY="<dir>" (e.g. /var/tftp)
    • Change options: TFTP_OPTIONS="[opt]*" (see the most relevant options below)
    • Option --secure: Change the root directory to the specified TFTP_DIRECTORY directory.
    • Option --create: Allow clients to upload new files. Existing files may be changed regardless.
  3. Fix folder permissions:
    • Make sure tftp:tftp has read access.
    • If it needs to be TFTP writable, make sure tftp:tftp has write access to it.
  4. Restart it: systemctl restart tftpd-hpa

Unbound

Setup

  1. Install: apt install unbound dns-root-data
    • It may fail to start due to systemd-resolved listening to the DNS UDP port.
  2. Setup the config: /etc/unbound/unbound.conf
  3. Make sure /etc/hosts contains the short and FQDN hostnames.
  4. Setup systemd-resolved:
    1. Open /etc/resolv.conf.
    2. Set DNSStubListener=no.
    3. Set DNS=::1.
    4. Restart systemd-resolved.
  5. Setup resolv.conf:
    1. Open /etc/resolv.conf.
    2. Set:
       nameserver 127.0.0.1
       nameserver ::1
       domain <domain>
       search <domain-list>
      
  6. Restart unbound: systemctl restart unbound
  7. Test DNSSEC:
    • drill sigfail.verteiltesysteme.net should give an rcode of SERVFAIL.
    • drill sigok.verteiltesysteme.net should give an rcode of NOERROR.
  8. Make sure dns-root-data is updating root hints in file /usr/share/dns/root.hints.

Notes

UniFi

See Ubiquiti UniFi Controllers.

WireGuard

Installation

  1. Install: apt install wireguard
  2. (Debian) Fix broken DNS (using systemd resolved):
    1. Enable systemd resolved: See systemd-resolved (Debian server setup).
    2. Fix missing resolvconf: ln -s /usr/bin/resolvectl /usr/local/bin/resolvconf

Usage

Example tunnel config:

[Interface]
# Generate with "wg genkey"
PrivateKey = <HIDDEN>
# Address for the local tunnel interface
Address = 10.234.0.3/31, 2a0f:9400:800f:ff01::1/127
DNS = 1.1.1.1, 2606:4700:4700::1111

[Peer]
# Get with "echo <privkey> | wg pubkey"
PublicKey = <HIDDEN>
# Add static route and reverse path filtering
# "0.0.0.0/0, ::/0" means this will be the default gateway, capturing all traffic
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = vpn.oolacile.hon.systems.:51823
# Keep the connection alive to keep firewall state alive (not very stealthy, though)
PersistentKeepalive = 25

ZFS

See Storage: ZFS.


hon.one | HON95/wiki | Edit page