gitlabwebhookssystemd

Webhook service isn't triggering


I have a webhook configured in GitLab. When I trigger it using the "Test" function, it shows a status code 200. On the target machine a systemd service is listening for that webhook, and is supposed to execute a build script. If I run the script directly, all is fine. How can I set up the webhook service so that it receives the notification from GitLab?

This is how I set the service up in Ansible:

- name: Create the webhooks service
  copy:
    dest: /etc/systemd/system/webhook.service
    content: |
      [Unit]
      Description=Webhooks
      [Service]
      ExecStart=/usr/bin/webhook -secure \
      -cert /etc/letsencrypt/live/my-project.mywebsite.com/fullchain.pem \
      -key /etc/letsencrypt/live/my-project.mywebsite.com/privkey.pem \
      -hooks /home/myuser/webhooks/hooks.json \
      -hotreload \
      -verbose
      WorkingDirectory=/home/myuser/webhooks
      Restart=always
      RestartSec=5
      [Install]
      WantedBy=multi-user.target

- name: Enable the webhooks service
  command: systemctl enable webhook.service

- name: (Re-)start the webhooks service
  command: systemctl restart webhook.service

This is my /home/myuser/webhooks/hooks.json:

[{
  "id": "my-repository",
  "execute-command": "/home/myuser/webhooks/my-repository/deploy.sh",
  "command-working-directory": "/home/myuser/my-repository/",
  "response-message": "Executing deploy script...",
  "trigger-rule": {
    "match": {
      "type": "payload-hmac-sha1",
      "secret":"<WEBHOOK_SECRET_LIKE_IN_GITLAB>",
      "parameter": {
        "source": "header",
        "name": "X-Hub-Signature"
      }
    }
  }
}]

I can confirm that the service is listening on the correct port, (9000 is default for webhooks):

myuser@mymachine:~$ sudo lsof -i -P -n | grep 9000
webhook   609262            root    6u  IPv6 1589700      0t0  TCP *:9000 (LISTEN)

Both the GitLab server and the target machine are on the same private Hetzner network. GitLab is on 10.0.2.1, the target machine is on 10.0.3.1.

The systemd service is running:

myuser@mymachine:~$ sudo systemctl status webhook.service
● webhook.service - Webhooks
     Loaded: loaded (/etc/systemd/system/webhook.service; enabled; preset: enabled)
     Active: active (running) since Tue 2024-10-08 18:42:34 UTC; 23s ago
   Main PID: 637049 (webhook)
      Tasks: 9 (limit: 18692)
     Memory: 2.1M (peak: 2.4M)
        CPU: 8ms
     CGroup: /system.slice/webhook.service
             └─637049 /usr/bin/webhook -secure -cert /etc/letsencrypt/live/my-project.mywebsite.com/fullchain.pem -key /etc/letsencrypt/live/my-project.mywebsite.com/privkey.pem -hooks >

Oct 08 18:42:34 my-project.mywebsite.com systemd[1]: Started webhook.service - Webhooks.
Oct 08 18:42:34 my-project.mywebsite.com webhook[637049]: [webhook] 2024/10/08 18:42:34 version 2.8.0 starting
Oct 08 18:42:34 my-project.mywebsite.com webhook[637049]: [webhook] 2024/10/08 18:42:34 setting up os signal watcher
Oct 08 18:42:34 my-project.mywebsite.com webhook[637049]: [webhook] 2024/10/08 18:42:34 attempting to load hooks from /home/myuser/webhooks/hooks.json
Oct 08 18:42:34 my-project.mywebsite.com webhook[637049]: [webhook] 2024/10/08 18:42:34 found 1 hook(s) in file
Oct 08 18:42:34 my-project.mywebsite.com webhook[637049]: [webhook] 2024/10/08 18:42:34         loaded: my-repository
Oct 08 18:42:34 my-project.mywebsite.com webhook[637049]: [webhook] 2024/10/08 18:42:34 os signal watcher ready
Oct 08 18:42:34 my-project.mywebsite.com webhook[637049]: [webhook] 2024/10/08 18:42:34 setting up file watcher for /home/myuser/webhooks/hooks.json
Oct 08 18:42:34 my-project.mywebsite.com webhook[637049]: [webhook] 2024/10/08 18:42:34 serving hooks on https://0.0.0.0:9000/hooks/{id}

Solution

  • This /home/myuser/webhooks/hooks.json would only work for GitHub. GitLab doesn't send the X-Hub-Signature header, and in fact, doesn't seem to sign its responses. Instead, it just sends the secret in the header, and webhook then compares it to the one in the json. The correct hook definition for GitLab looks like this:

    [{
      "id": "my-repository",
      "execute-command": "/home/myuser/webhooks/my-repository/deploy.sh",
      "command-working-directory": "/home/myuser/my-repository/",
      "response-message": "Executing deploy script...",
      "trigger-rule": {
        "match": {
          "type": "value",
          "parameter": {
            "source": "header",
            "name": "X-Gitlab-Token"
          },
          "value": "<WEBHOOK_SECRET_LIKE_IN_GITLAB>"
        }
      }
    }]
    

    Also, I added these two flags in the service definition:
    tls-min-version 1.3 and http-methods POST. The former is fine, as I know that GitLab supports TLS v1.3 and I know my machine does as well, the latter since I only have one webhook and it uses POST.