guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

01/01: hydra: Add initial configuration of berlin.


From: Ricardo Wurmus
Subject: 01/01: hydra: Add initial configuration of berlin.
Date: Thu, 20 Jul 2017 17:43:43 -0400 (EDT)

rekado pushed a commit to branch master
in repository maintenance.

commit 7d1f97258b9071a227a8c4e191f74b59dae325ef
Author: Ricardo Wurmus <address@hidden>
Date:   Thu Jul 20 23:42:37 2017 +0200

    hydra: Add initial configuration of berlin.
    
    * hydra/berlin.scm: New file.
    * hydra/nginx/berlin.conf: New file.
---
 hydra/berlin.scm        | 284 ++++++++++++++++++++++++++++++++++++++++++++++++
 hydra/nginx/berlin.conf | 145 ++++++++++++++++++++++++
 2 files changed, 429 insertions(+)

diff --git a/hydra/berlin.scm b/hydra/berlin.scm
new file mode 100644
index 0000000..44b4796
--- /dev/null
+++ b/hydra/berlin.scm
@@ -0,0 +1,284 @@
+;; OS configuration for "berlin", the frontend of the compile farm
+;; hosted at the MDC.
+
+(use-modules (gnu) (guix) (sysadmin people))
+(use-service-modules base networking admin mcron shepherd ssh web cuirass)
+(use-package-modules admin emacs linux ssh tls vim package-management web wget 
ci)
+
+(define (maintenance-file name)
+  (local-file (string-append "/root/maintenance/hydra/" name)))
+
+(define %sysadmins
+  ;; The sysadmins.
+  (list (sysadmin (name "ludo")
+                  (full-name "Ludovic Courtès")
+                  (lsh-public-key (maintenance-file "keys/lsh/ludo.pub")))
+        (sysadmin (name "rekado")
+                  (full-name "Ricardo Wurmus")
+                  (lsh-public-key (maintenance-file "keys/lsh/rekado.pub")))
+        (sysadmin (name "andreas")
+                  (full-name "Andreas Enge")
+                  (lsh-public-key (maintenance-file "keys/lsh/andreas.pub")))
+        ;; (sysadmin (name "bi-admin")
+        ;;           (full-name "MDC admin")
+        ;;           (lsh-public-key (maintenance-file 
"keys/lsh/bi-admin.pub")))
+        ))
+
+
+(define %gc-job
+  ;; The garbage collection mcron job, once per day.
+  #~(job '(next-hour '(4))
+         (string-append #$guix "/bin/guix gc -F80G")))
+
+(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 %guix-daemon-config
+  (guix-configuration
+   ;; Disable substitutes altogether.
+   (use-substitutes? #f)
+   (substitute-urls '())
+   (authorized-keys '())
+   (max-silent-time 7200)
+   (timeout (* 4 max-silent-time))
+
+   (extra-options '("--max-jobs=5" "--cores=4" ;we have 8 cores
+                    "--cache-failures"
+                    "--gc-keep-outputs" "--gc-keep-derivations"))))
+
+(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
+  ;; <http://www.la-samhna.de/library/brutessh.html#3>.
+  #~(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)))))
+
+
+;;;
+;;; NGINX.
+;;;
+
+(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 "/root/berlin-nginx.conf") 
"berlin.conf")
+                       (copy-file #$(local-file
+                                     
"/root/maintenance/hydra/nginx/bayfront-locations.conf")
+                                  "berlin-locations.conf")
+                       (substitute* "berlin-locations.conf"
+                         (("@WWWROOT@")
+                          #$(local-file "/root/maintenance/hydra/nginx/html" 
#:recursive? #t)))))))
+
+(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")))))
+
+(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")))))
+
+
+;;;
+;;; Cuirass.
+;;;
+
+(define %cuirass-specs
+  ;; Cuirass specifications to build Guix.
+  #~(list `((#:name . "guix")
+            ;; FIXME: The campus firewall blocks access to git://
+            (#:url . "https://git.savannah.gnu.org/git/guix.git";)
+            (#:load-path . ".")
+
+            ;; FIXME: Currently this must be an absolute file name because
+            ;; the 'evaluate' command of Cuirass loads it with
+            ;; 'primitive-load'.
+            ;; Use our own variant of Cuirass' 'examples/gnu-system.scm'.
+            (#:file . #$(local-file 
"/root/maintenance/hydra/cuirass-jobs.scm"))
+            (#:no-compile? #t)      ;don't try to run ./bootstrap etc.
+
+            (#:proc . hydra-jobs)
+            (#:arguments (subset . "all"))
+            (#:branch . "master"))))
+
+
+;;;
+;;; Operating system.
+;;;
+
+(define %motd
+  ;; Message of the day!  Libcaca's img2txt gives something that's not so
+  ;; great.
+  (plain-file "motd"
+              "\
+ :                               .
+ S:                            S
+  : 8  . . :8         t . . .  ;
+     %888.   ;       :   SX8@
+          t 8       %  .
+           .8 8     .
+           .88     t  :     Welcome to berlin!
+            .  t   .8
+             .  % .  8
+             8   8 8
+              .  X  8
+              8 address@hidden
+
+Best practices:
+
+  1. Store everything in guix-maintenance.git.
+  2. Use the Git checkouts of Guix and guix-maintenance in ~root.
+  3. Notify address@hidden when reconfiguring.
+  4. Notify address@hidden when something goes wrong.
+
+  5. Notify address@hidden or address@hidden when the
+     machine doesn't respond.  Only Ricardo has access to the serial console
+     to reset the machine.
+
+Happy hacking!\n"))
+
+
+(operating-system
+  (host-name "berlin.guixsd.org")
+  (timezone "Europe/Berlin")
+  (locale "en_US.utf8")
+
+  ;; Allow access through the serial console at 141.80.113.141; the
+  ;; management interface can only be accessed through selected
+  ;; servers within the MDC campus network.
+  (kernel-arguments '("console=tty0"
+                      "console=ttyS1,9600n8"))
+
+  ;; The SunFire X2200 M2 servers need this kernel module for their
+  ;; disk controllers.
+  (initrd (lambda (fs . args)
+            (apply base-initrd fs
+                   #:extra-modules (list "sata_nv")
+                   args)))
+
+  ;; Show the GRUB menu on the serial interface.
+  (bootloader (grub-configuration (device "/dev/sda")
+                                  (terminal-inputs '(serial))
+                                  (terminal-outputs '(serial))))
+
+  ;; Just a single disk, no RAID :-/
+  (file-systems (cons (file-system
+                        (device "my-root")
+                        (title 'label)
+                        (mount-point "/")
+                        (type "ext4"))
+                      %base-file-systems))
+
+  ;; Local admin account for MDC maintenance.
+  (users (cons (user-account
+                (name "bi-admin")
+                (comment "Local admin")
+                (group "users")
+                (supplementary-groups '("wheel"))
+                (home-directory "/home/bi-admin"))
+               %base-user-accounts))
+
+  (packages (cons* certbot emacs wget iptables
+                   jnettop lm-sensors openssh
+                   %base-packages))
+
+  (services (cons*
+             (service sysadmin-service-type %sysadmins)
+
+             ;; TODO: configure the second network interface once it's
+             ;; hooked up to the switch.
+             (static-networking-service "enp6s4f0"
+                                        "141.80.181.40"
+                                        #:netmask "255.255.255.0"
+                                        #:gateway "141.80.181.1")
+             (lsh-service #:port-number 22)
+
+             ;; Allow login over serial console.
+             (agetty-service (agetty-configuration
+                              (tty "ttyS1")
+                              (baud-rate "9600")))
+
+             ;; The Web service.
+             (service guix-publish-service-type
+                      (guix-publish-configuration
+                       (port 3000)
+                       (cache "/var/cache/guix/publish")
+                       (ttl (* 45 24 3600))
+                       (compression-level 9)
+                       (workers 8)))
+
+             (nginx-service #:config-file
+                            (file-append %nginx-config
+                                         "/berlin.conf"))
+             %nginx-mime-types
+             %nginx-cache-activation
+
+             (service cuirass-service-type
+                      (cuirass-configuration
+                       (interval (* 5 60))
+                       (specifications %cuirass-specs)))
+
+             ;; Make SSH and HTTP/HTTPS available over Tor.
+             (tor-hidden-service "http"
+                                 '((22 "127.0.0.1:22")
+                                   (80 "127.0.0.1:80")
+                                   (443 "127.0.0.1:443")))
+             (tor-service)
+
+             ;; Cron and log rotation.
+             (service rottlog-service-type (rottlog-configuration))
+             (service mcron-service-type
+                      (mcron-configuration
+                       (jobs (list %gc-job %certbot-job))))
+
+             firewall-service
+
+             (modify-services %base-services
+               ;; Disable substitutes altogether.
+               (guix-service-type config => %guix-daemon-config)
+               (login-service-type
+                config => (login-configuration
+                           (inherit config)
+                           (motd %motd)))))))
diff --git a/hydra/nginx/berlin.conf b/hydra/nginx/berlin.conf
new file mode 100644
index 0000000..f3272e5
--- /dev/null
+++ b/hydra/nginx/berlin.conf
@@ -0,0 +1,145 @@
+# This is the nginx config file for berlin.guixsd.conf.
+
+user nginx;
+worker_processes  auto;
+
+error_log  /var/log/nginx/error.log error;
+pid        /var/run/nginx.pid;
+
+pcre_jit   on;
+
+events {
+    worker_connections  1024;
+}
+
+http {
+    include /etc/nginx/mime.types;
+    default_type  application/octet-stream;
+
+    # We need to specify all these or nginx picks its own directory to
+    # store them, which doesn't work because the store is read-only.
+    client_body_temp_path /var/run/nginx/body;
+    proxy_temp_path       /var/run/nginx/proxy;
+    fastcgi_temp_path     /var/run/nginx/fastcgi;
+    uwsgi_temp_path       /var/run/nginx/uwsgi;
+    scgi_temp_path        /var/run/nginx/scgi;
+
+    access_log /var/log/nginx/access.log;
+
+    sendfile        on;
+
+    # Maximum chunk size to send.  Partly this is a workaround
+    # for <http://bugs.gnu.org/19939>, but also the nginx docs
+    # mention that "Without the limit, one fast connection may
+    # seize the worker process entirely."
+    # <http://nginx.org/en/docs/http/ngx_http_core_module#sendfile_max_chunk>
+    sendfile_max_chunk 1m;
+
+    keepalive_timeout  65;
+
+    # Use HTTP 1.1 to talk to the backend so we benefit from
+    # keep-alive connections and chunked transfer encoding.  The
+    # latter allows us to make sure we do not cache partial downloads.
+    proxy_http_version 1.1;
+
+    # The 'inactive' parameter for caching is not very useful in our
+    # case: all that matters is that LRU sweeping happens when
+    # 'max_size' is hit.
+
+    # cache for narinfo files
+    proxy_cache_path /var/cache/nginx/narinfo
+                    levels=2
+                    inactive=7d           # inactive keys removed after 7d
+                    keys_zone=narinfo:4m  # narinfo meta data: ~32K keys
+                    max_size=5g;          # total cache data size max
+
+    # cache for nar files
+    proxy_cache_path /var/cache/nginx/nar
+                    levels=2
+                    inactive=8d           # inactive keys removed after 8d
+                    keys_zone=nar:4m      # nar cache meta data: ~32K keys
+                    max_size=50g;         # total cache data size max
+
+    # cache for content-addressed files
+    proxy_cache_path /var/cache/nginx/cas
+                    levels=2
+                    inactive=180d         # inactive keys removed after 180d
+                    keys_zone=cas:8m      # nar cache meta data: ~64K keys
+                    max_size=30g;         # total cache data size max
+
+    # cache for build logs
+    proxy_cache_path /var/cache/nginx/logs
+                    levels=2
+                    inactive=60d          # inactive keys removed after 60d
+                    keys_zone=logs:8m     # narinfo meta data: ~64K keys
+                    max_size=4g;          # total cache data size max
+
+    # cache for static data
+    proxy_cache_path /var/cache/nginx/static
+                    levels=1
+                    inactive=10d          # inactive keys removed after 10d
+                    keys_zone=static:1m   # nar cache meta data: ~8K keys
+                    max_size=200m;        # total cache data size max
+
+    # If Hydra cannot honor these delays, then something is wrong and
+    # we'd better drop the connection and return 504.
+    proxy_connect_timeout 7s;
+    proxy_read_timeout 10s;
+    proxy_send_timeout 10s;
+
+    # Cache timeouts for a little while to avoid increasing pressure.
+    proxy_cache_valid 504 30s;
+
+    server {
+        listen       80;
+        server_name  berlin.guixsd.org;
+
+        access_log  /var/log/nginx/http.access.log;
+
+        proxy_set_header X-Forwarded-Host $host;
+        proxy_set_header X-Forwarded-Port $server_port;
+        proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
+
+        include berlin-locations.conf;
+    }
+
+    server {
+        listen       80;
+        server_name  bootstrappable.org;
+        root         /home/rekado/bootstrappable.org;
+        index        index.html;
+        access_log   /var/log/nginx/bootstrappable.access.log;
+        location = / {
+          root /home/rekado/bootstrappable.org;
+        }
+    }
+
+    # HTTPS server.
+    server {
+        listen       443 ssl;
+        server_name  berlin.guixsd.org;
+
+        ssl_certificate     
/etc/letsencrypt/live/berlin.guixsd.org/fullchain.pem;
+        ssl_certificate_key 
/etc/letsencrypt/live/berlin.guixsd.org/privkey.pem;
+
+        # Make sure SSL is disabled.
+        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
+
+        # Disable weak cipher suites.
+        ssl_ciphers         HIGH:!aNULL:!MD5;
+        ssl_prefer_server_ciphers on;
+
+        # Use our own DH parameters created with:
+        #    openssl dhparam -out dhparams.pem 2048
+        # as suggested at <https://weakdh.org/sysadmin.html>.
+        ssl_dhparam         /etc/dhparams.pem;
+
+        access_log  /var/log/nginx/https.access.log;
+
+        proxy_set_header X-Forwarded-Host $host;
+        proxy_set_header X-Forwarded-Port $server_port;
+        proxy_set_header X-Forwarded-For  $proxy_add_x_forwarded_for;
+
+        include berlin-locations.conf;
+    }
+}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]