A fundamental principle of MOOSE is that servers are treated like “cattle” as much as possible, but with their own individual “pet” personality. To achieve this we built Salt “states” to consistently deploy servers, but those templates are configurable through “grains”. The actual grain data is stored in YAML format in /etc/salt/grains
on your server.
The grains interface presents Salt with “grains of information” including default values such as domain name, IP address, kernel version, OS type, memory and many other properties of the system. We have extended this interface to allow common systems administration tasks to be simplified, and those customisations to be easily copied across a fleet of similar servers.
Using Grains
Setting a Grain
The easiest way to set a grain is from the command-line while logged in as root:
root@moose:~# salt-call grains.set moose:owner:name "Monty the Network Moose"
This sets the name
key of the owner
array within the moose
array to the string value Monty the Network Moose
. The command will return the structure of the topmost array (in this case moose
):
local:
----------
changes:
----------
moose:
----------
owner:
----------
name:
Monty the Network Moose
url:
https://twitter.com/NetworkMoose
Applying States
Once grains have been set or changed the entire set of templates can be re-applied to the server with one command. This wil take a several seconds to run, depending on how large the set of changes are:
root@moose:~# salt-call state.highstate --state-output=mixed
This “highstate” command (which applies all relevant states to the server) will output brief information about all the individual configuration items which have been applied, as well as a summary at the end:
Summary for local
-------------
Succeeded: 316 (changed=32)
Failed: 0
-------------
Total states run: 316
Total run time: 191.106 s
Showing Grains
To show all the grains:
root@moose:~# salt-call grains.items
To show one specific part of the grains:
root@moose:~# salt-call grains.get moose:owner
Unsetting a Grain
To remove the value set for a particular grain:
root@moose:~# salt-call grains.delkey moose:owner:url
You may need to force this:
root@moose:~# salt-call grains.delkey firewall:tcp4:12345 force=True
System
fqdn
and domain
The fully-qualified domain name is used as the main identifier for your server. Your server overview page will be made available at this address.
fqdn: server.example.com
domain: example.com
moose:packages
This is a list of extra packages to install. We recommend using this if you want to be able to deploy an identical instance of your machine from a barebones installation
moose:
packages:
- vim
- emacs24-nox
To set a list of values like this, the syntax is:
root@moose:~# salt-call grains.set moose:packages '["vim","emacs24-nox"]'
cron
Contains a mapping of hours and minutes (past the hour) for hourly, daily, weekly, and monthly cronjobs. These are set randomly the first time your server is provisioned. This helps spread the workload and prevent a “thundering herd” during daily maintenance tasks such as backups. Weekly jobs always run on Sunday. Monthly jobs always run on the first day of the month.
cron:
hourly:
minute: '17'
daily:
hour: '6'
minute: '25'
weekly:
hour: '6'
minute: '47'
monthly:
hour: '6'
minute: '52'
email
A list of email addresses to receive automated information from server. Some packages only support one recipient, and so only the first item in the list will be used.
email:
default:
- webmaster@example.com
- alice@example.com
- bob@example.com
security:
- hostmaster@example.com
- charlie@example.com
moose:owner
It is possible to show the owner of your server on its overview page.
moose:
owner:
name: Network Moose
url: https://twitter.com/NetworkMoose
Security
firewall
Deploy a firewall on using netfilter-persistent
. On modern hosts this will generate /etc/nftables.conf
which will be applied at system startup.
firewall:
tcp4:
22:
46.227.200.128/28: FAELIX Admin VPN
185.134.196.22/28: FAELIX Admin VPN
192.0.2.0/24: our network
80: {}
443: {}
udp4:
53:
192.0.2.0/24: our network
443: {}
tcp6:
22:
2a01:9e00:a217:fa00::/56: FAELIX Admin VPN
2a01:9e01:a217:fa00::/56: FAELIX Admin VPN
2001:db8::/32: our network
80: {}
443: {}
udp6:
53:
2001:db8::/32: our network
443: {}
Each port number is an array mapping each permitted subnet to a comment.
root@moose:~# salt-call grains.set firewall:tcp4:12345:192.0.2.0/24 "permit our own network"
To open the port to the world, use an empty array (i.e. no restrictions).
root@moose:~# salt-call grains.set firewall:tcp4:80 '{}'
To close the port back down again, delete the reference to the port:
root@moose:~# salt-call grains.delkey firewall:tcp4:12345
root
root:
authorized_keys:
faelix_noc: True
faelix_soc: True
sshd
sshd:
installed: True
port: 22
listenaddress:
- '0.0.0.0'
- '::'
permitrootlogin: 'prohibit-password'
passwordauthentication: 'yes'
challengeresponseauthentication: 'yes'
maxauthtries: 3
maxsessions: 10
x11forwarding: 'no'
allowtcpforwarding: 'yes'
allowagentforwarding: 'yes'
tcpkeepalive: 'yes'
permittunnel: 'yes'
printmotd: 'no'
printlastlog: 'yes'
compression: 'yes'
banner: null
usedns: 'yes'
logingracetime: '10m'
loglevel: 'INFO'
lynis
lynis:
skip-tests:
- SSH-7408:permitrootlogin
- SSH-7408:port
- FILE-6310
- FIRE-4513
- LOGG-2190
email:security
A list of email addresses to receive alerts about the security posture of your server. Some packages only support one recipient, and so only the first item in the list will be used.
email:
security:
- hostmaster@example.com
- security@example.com
If unset, email:default
will be used instead.
Hostname Resolution
moose:network
If set to “dynamic” then /etc/resolv.conf will not be autoconfigured.
moose:nameservers
A list of nameservers. Defaults to Faelix’s standard ones.
moose:
nameservers:
- "46.227.200.54"
- "46.227.200.55"
moose:hosts
Static hostname to IP address mappings.
moose:
hosts:
"192.0.2.1":
- myrouter.example.com
- myrouter
"2001:db8::42":
- myrouter.example.com
- myrouter
The above example will become the following in /etc/hosts
:
192.0.2.1 myrouter.example.com myrouter
2001:db8::42 myrouter.example.com myrouter
Backup
backup:borg
Use borgbackup to automatically store snapshots of the server. This is used to generate the /etc/cron.daily/borgbackup
script and its configuration file /etc/faelix/moose/borgbackup
.
At a minimum both backup:borg:destination
and backup:borg:passphrase
need to be set. Extra backup repositories can be set under the repo
key, with their own retention policy and exclusion lists.
backup:
borg:
destination: borg1.w.faelix.net
user: borg
passphrase: gibberishJGVRM8L3ZYAQWAJTpassword
repo:
owncloud:
path: /var/www/owncloud
exclude:
- /var/www/owncloud/data/*.log
keep_daily: 7
keep_monthly: 1
keep_weekly: 1
Monitoring
collectd:faelix
Explicitly set this to False
if you do not with for statistics to be sent to FAELIX’s collectd service.
collectd:
faelix: True
collectd:servers
Other servers to send collectd statistics to.
collectd:
servers:
192.0.2.1:
username: foo
password: bar
securitylevel: Encrypt
port: 25826
collectd:user_suffix
and collectd:password
The username and password used to send packets to Faelix’s monitoring systems is specified by these two grains. Changing them will probably prevent expected functioning.
collectd:ping
Specify extra hosts you would like to ping from your server as a list.
collectd:
ping:
hosts:
- "192.0.2.1"
- "192.0.2.2"
- "2001:db8::13"
interval: 8
timeout: 0.9
source_address: "192.0.2.254"
device: eth0
Web Server
php
php:
max_execution_time: 30
error_reporting: "E_ALL & ~E_DEPRECATED & ~E_STRICT"
memory_limit: "128M"
max_input_time: 60
post_max_size: "128M"
upload_max_filesize: "128M"
max_file_uploads: 32
default_socket_timeout: 60
date_timezone: UTC
xcache
xcache:
admin:
password: FxU35eJ2Ow6vsNh1
cacher: False
xcache:cacher
Set this to False on systems where you encounter problems caused by XCache.
Mail Server
postfixadmin
When Postfix Admin is installed, databases are automatically created and the credentials recorded here. Three different MySQL users are created, one for each of the various components that need to query the postfixadmin
database.
postfixadmin:
pfa-dovecot:
password: YnQquVWHy3G52fE6
pfa-postfix:
password: a34Iv36SsEP7D7Do
pfa-vacation:
password: K23SQCK0na6Ye0qU
postfix
postfix:
smtp_tls_security_level: may
smtpd_tls_security_level: may
smtpd_tls_eecdh_grade: strong
tls_eecdh_strong_curve: prime256v1
tls_eecdh_ultra_curve: secp384r1
tls:
v12: False
tls_policy_map:
example.com: encrypt
roundcube
roundcube:
config:
des_key: ot4wAP3yYQzAIXHz3hF4lhxd
mysql:
password: k24Nxy66U0aeIQ0r
amavis
amavis:
sa_spam_subject_tag: "***SPAM***"
sa_tag_level_deflt: -999
sa_tag2_level_deflt: 6.31
sa_kill_level_deflt: 6.31
sa_dsn_cutoff_level: 10
sa_mail_body_size_limit: "200*1024"
sa_local_tests_only: False
final_virus_destiny: D_DISCARD
final_banned_destiny: D_REJECT
final_spam_destiny: D_DISCARD
final_bad_header_destiny: D_PASS
cron_tidy_quarantine_days: 28
ntp
ntp:
servers:
ntp2.inrim.it: {}
time-a.nist.gov: {}
stdtime.gov.hk: {}
ntp.ix.ru: {}
46.227.200.70:
flags:
- iburst
46.227.200.72:
flags:
- iburst
185.134.196.166:
flags:
- iburst
- peer
127.127.1.0:
fudge:
stratum: 11
nginx
nginx:
release: vendor
ssl_protocols: "TLSv1 TLSv1.1 TLSv1.2"
client_max_body_size: "128m"
php
php:
release: distribution
distribution
for the version of PHP included in your server’s operation system distribution7.0
for PHP 7.0 from packages.sury.org7.2
for PHP 7.2 from packages.sury.org7.3
for PHP 7.3 from packages.sury.org7.4
for PHP 7.4 from packages.sury.org8.0
for PHP 8.0 from packages.sury.org
nextcloud
nextcloud:
host: cloud.example.com