;;; GNU Guix system administration tools. ;;; ;;; Copyright (C) Nils Gillmann ;;; Parts and pieces initially taken from Guix' maintenance repository: ;;; Copyright © 2016, 2017, 2018 Ludovic Courtès ;;; Copyright © 2017, 2018 Ricardo Wurmus ;;; ;;; This program is free software: you can redistribute it and/or modify ;;; it under the terms of the GNU General Public License as published by ;;; the Free Software Foundation, either version 3 of the License, or ;;; (at your option) any later version. ;;; ;;; This program is distributed in the hope that it will be useful, ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;; GNU General Public License for more details. ;;; ;;; You should have received a copy of the GNU General Public License ;;; along with this program. If not, see . (define-module (sysadmin services) #:use-module (guix gexp) #:use-module (gnu services) #:use-module (gnu services admin) #:use-module (gnu services base) #:use-module (gnu services cuirass) #:use-module (gnu services mcron) #:use-module (gnu services shepherd) #:use-module (gnu services ssh) #:use-module (gnu services web) #:use-module (gnu packages linux) #:use-module (gnu packages package-management) #:use-module (gnu packages tls) #:use-module (gnu packages web) #:use-module (sysadmin people) #:use-module (srfi srfi-1) #:export (firewall-service default-services)) (define start-firewall ;; Rules to throttle malicious SSH connection attempts. This will allow at ;; most 3 connections per minute from any host, and will block the host for ;; another minute if this rate is exceeded. Taken from ;; . #~(let ((iptables (lambda (str) (zero? (apply system* #$(file-append iptables "/sbin/iptables") (string-tokenize str)))))) (format #t "Installing iptables SSH rules...~%") (and (iptables "-A INPUT -p tcp --dport 22 -m state \ --state NEW -m recent --set --name SSH -j ACCEPT") (iptables "-A INPUT -p tcp --dport 22 -m recent \ --update --seconds 60 --hitcount 4 --rttl \ --name SSH -j LOG --log-prefix SSH_brute_force") (iptables "-A INPUT -p tcp --dport 22 -m recent \ --update --seconds 60 --hitcount 4 --rttl --name SSH -j DROP")))) (define firewall-service ;; The "firewall". Make it a Shepherd service because as an activation ;; script it might run too early, before the Netfilter modules can be ;; loaded for some reason. (simple-service 'firewall shepherd-root-service-type (list (shepherd-service (provision '(firewall)) (requirement '()) (start #~(lambda () #$start-firewall)) (respawn? #f))))) (define %nginx-config ;; Our nginx configuration directory. It expects 'guix publish' to be ;; running on port 3000. (computed-file "nginx-config" (with-imported-modules '((guix build utils)) #~(begin (use-modules (guix build utils)) (mkdir #$output) (chdir #$output) (symlink #$(local-file "nginx/berlin.conf") "berlin.conf") (copy-file #$(local-file "nginx/bayfront-locations.conf") "berlin-locations.conf") (substitute* "berlin-locations.conf" (("@WWWROOT@") #$(local-file "nginx/html/berlin" #:recursive? #t))))))) (define %nginx-cache-activation ;; Make sure /var/cache/nginx exists on the first run. (simple-service 'nginx-/var/cache/nginx activation-service-type (with-imported-modules '((guix build utils)) #~(begin (use-modules (guix build utils)) (mkdir-p "/var/cache/nginx"))))) (define %nginx-mime-types ;; Provide /etc/nginx/mime.types (and a bunch of other files.) (simple-service 'nginx-mime.types etc-service-type `(("nginx" ,(file-append nginx "/share/nginx/conf"))))) ;; FIXME: Use certbot-service. ;; Initial list of domains: ;; taler.net www.taler.net api.taler.net lcov.taler.net git.taler.net ;; gauger.taler.net buildbot.taler.net test.taler.net playground.test.taler.net ;; auditor.test.taler.net auditor.demo.taler.net demo.taler.net shop.test.taler.net ;; shop.demo.taler.net survey.test.taler.net survey.demo.taler.net ;; donations.demo.taler.net backend.test.taler.net backend.demo.taler.net ;; bank.test.taler.net bank.demo.taler.net www.git.taler.net ;; exchange.demo.taler.net exchange.test.taler.net env.taler.net ;; envs.taler.net blog.demo.taler.net blog.test.taler.net ;; donations.test.taler.net docs.taler.net intranet.taler.net ;; stage.taler.net (define %certbot-job ;; Attempt to renew the Let's Encrypt certificate twice a week. #~(job (lambda (now (next-day-from (next-hour-from now '(3)) '(2 5))) (string-append #$certbot "/bin/certbot renew")))) (define* (default-services sysadmins #:key nginx-config-file) "Return the list of default services." (cons* (service rottlog-service-type (rottlog-configuration)) (service mcron-service-type (mcron-configuration (jobs (list %certbot-job)))) firewall-service (service nginx-service-type (nginx-configuration (file nginx-config-file))) %nginx-mime-type %nginx-cache-activation (service openssh-service-type) (service sysadmin-service-type sysadmins)))