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
distributionfor the version of PHP included in your server’s operation system distribution7.0for PHP 7.0 from packages.sury.org7.2for PHP 7.2 from packages.sury.org7.3for PHP 7.3 from packages.sury.org7.4for PHP 7.4 from packages.sury.org8.0for PHP 8.0 from packages.sury.org
nextcloud
 nextcloud:
  host: cloud.example.com