gatus.sh (5539B)
1 #!/usr/bin/env bash 2 3 set -o errexit 4 set -o nounset 5 set -o xtrace 6 7 # Prepare environment 8 export DEBIAN_FRONTEND=noninteractive 9 GATUS_BUILD_DIR=/opt/gatus 10 GATUS_TLS_DIR=/etc/nginx/tls 11 GATUS_CONFIG_PATH=/etc/gatus.yaml 12 13 mkdir -p $GATUS_BUILD_DIR 14 mkdir -p $GATUS_TLS_DIR 15 16 # Prepare Gatus user/group 17 useradd -M -r gatus 18 19 # Update system 20 apt-get install -y apt-utils 21 apt-get update && apt-get upgrade -y 22 apt-get install -y curl nginx nfs-common fcgiwrap socat 23 24 # Install Go (https://go.dev/doc/install) 25 cd $GATUS_BUILD_DIR 26 curl -Lo go.tar.gz https://go.dev/dl/go1.20.7.linux-armv6l.tar.gz 27 tar -C /usr/local -xf go.tar.gz 28 export PATH=$PATH:/usr/local/go/bin 29 30 # Download Gatus 31 GATUS_VERSION=5.10.0 32 curl -Lo gatus.tar.gz https://github.com/TwiN/gatus/archive/refs/tags/v$GATUS_VERSION.tar.gz 33 tar -xf gatus.tar.gz 34 35 # Build Gatus 36 cd gatus-$GATUS_VERSION 37 CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o gatus . 38 39 # Install Gatus 40 mv gatus /usr/bin/gatus 41 42 # Configure Gatus (https://github.com/TwiN/gatus/tree/master#usage) 43 cat <<EOF > $GATUS_CONFIG_PATH 44 web: 45 address: 127.0.0.1 46 endpoints: 47 - name: website # Name of your endpoint, can be anything 48 url: "https://twin.sh/health" 49 interval: 5m # Duration to wait between every status check (default: 60s) 50 conditions: 51 - "[STATUS] == 200" # Status must be 200 52 - "[BODY].status == UP" # The json path "$.status" must be equal to UP 53 - "[RESPONSE_TIME] < 300" # Response time must be under 300ms 54 EOF 55 56 # Create Gatus Systemd service 57 # https://aur.archlinux.org/cgit/aur.git/tree/gatus.service?h=gatus 58 cat <<EOF > /etc/systemd/system/gatus.service 59 [Unit] 60 Description=Automated service health dashboard 61 Wants=network-online.target 62 After=network-online.target 63 64 [Service] 65 Type=simple 66 User=gatus 67 Group=gatus 68 ExecStart=/usr/bin/gatus web.address 69 Environment=GATUS_CONFIG_PATH=$GATUS_CONFIG_PATH 70 Restart=on-failure 71 NoNewPrivileges=yes 72 PrivateTmp=yes 73 PrivateDevices=yes 74 DevicePolicy=closed 75 ReadWritePaths=/var/lib/gatus 76 ProtectSystem=strict 77 ProtectHome=read-only 78 ProtectControlGroups=yes 79 ProtectKernelModules=yes 80 ProtectKernelTunables=yes 81 RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 AF_NETLINK 82 RestrictNamespaces=yes 83 RestrictRealtime=yes 84 RestrictSUIDSGID=yes 85 MemoryDenyWriteExecute=yes 86 LockPersonality=yes 87 ProtectClock=yes 88 ProtectHostname=yes 89 ProtectKernelLogs=yes 90 ProtectHome=yes 91 CapabilityBoundingSet=CAP_NET_RAW 92 AmbientCapabilities=CAP_NET_RAW 93 UMask=0077 94 SystemCallFilter=~@clock 95 SystemCallFilter=~@cpu-emulation 96 SystemCallFilter=~@debug 97 SystemCallFilter=~@module 98 SystemCallFilter=~@mount 99 SystemCallFilter=~@obsolete 100 SystemCallFilter=~@privileged 101 SystemCallFilter=~@raw-io 102 SystemCallFilter=~@reboot 103 SystemCallFilter=~@swap 104 105 [Install] 106 WantedBy=multi-user.target 107 EOF 108 109 # Mount TLS certificate 110 cat <<EOF >> /etc/fstab 111 $GATUS_TLS_NFS_SERVER $GATUS_TLS_DIR nfs rw 0 0 112 EOF 113 114 # Configure Nginx reverse proxy 115 cat <<EOF > /etc/nginx/conf.d/gatus.conf 116 server { 117 listen 443 ssl; 118 119 ssl_certificate $GATUS_TLS_DIR/live/up.in0rdr.ch/fullchain.pem; 120 ssl_certificate_key $GATUS_TLS_DIR/live/up.in0rdr.ch/privkey.pem; 121 122 location / { 123 proxy_pass http://127.0.0.1:8080; 124 proxy_set_header Host \$host; 125 proxy_set_header X-Real-IP \$remote_addr; 126 proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; 127 proxy_set_header X-Forwarded-Proto \$scheme; 128 } 129 } 130 131 server { 132 listen 127.0.0.1:9090; 133 134 # expose the collectd metrics 135 location /collectd { 136 include fastcgi_params; 137 fastcgi_param SCRIPT_FILENAME /usr/local/bin/collectd.sh; 138 fastcgi_param QUERY_STRING \$query_string; 139 fastcgi_pass unix:/run/fcgiwrap.socket; 140 } 141 } 142 EOF 143 144 # Allow Gatus to read config file 145 chown gatus: $GATUS_CONFIG_PATH 146 147 # Enable Gatus and Nginx 148 systemctl enable gatus 149 systemctl enable nginx 150 151 # Ensure tls on nfs before nginx starts 152 mkdir -p /etc/systemd/system/nginx.service.d 153 cat <<EOF > /etc/systemd/system/nginx.service.d/override.conf 154 [Service] 155 ExecStartPre= 156 ExecStartPre=/usr/bin/sh -c 'sleep 5 && mount -a' 157 ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;' 158 EOF 159 160 # Add collectd script to return stats as HTTP response 161 cat <<'EOF' > /usr/local/bin/collectd.sh 162 #!/usr/bin/env bash 163 # 164 # Depends: 165 # - fcgiwrap 166 # - socat 167 # 168 # https://landchad.net/cgi 169 170 COLLECTD_SOCK=/collectd/query.sock 171 #echo "LISTVAL" | socat - UNIX-CLIENT:$COLLECTD_SOCK 172 173 # We need the script primarily, because the collectd unix socket plugin does 174 # not return a proper http response. This line here fixes that behavior so it 175 # is a proper http response. Nginx will refuse to return the response from the 176 # unix upstream otherwise. Unfortunately, the Nginx add_header directive would 177 # only add the header starting from Nginx server (to the end client). 178 echo "Content-type: text/json" 179 echo 180 181 function get_df() { 182 free_e=$(echo "GETVAL $1/percent_bytes-free" | socat - UNIX-CLIENT:/$COLLECTD_SOCK | tail -1 | cut -d '=' -f2) 183 184 # convert from scientific notation 185 printf "%.0f\n" "$free_e" 186 } 187 188 function md_status(){ 189 md_status_e=$(echo "GETVAL turris/exec-$1/md_disks-degraded" | socat - UNIX-CLIENT:/$COLLECTD_SOCK | tail -1 | cut -d '=' -f2) 190 # convert from scientific notation 191 printf "%.0f\n" "$md_status_e" 192 } 193 194 df_srv=$(get_df "turris/df-srv") 195 df_nfs=$(get_df "turris/df-srv-nfs") 196 md_status=$(md_status "md127") 197 198 cat << EOF 199 { 200 "srv_free_percent":"$df_srv", 201 "nfs_free_percent":"$df_nfs", 202 "md_degraded":"$md_status" 203 } 204 EOF 205 chmod +x /usr/local/bin/collectd.sh