Skip to content

webhook service with TLS and Let's Encrypt certificate

For a number of services, I need a system/service which can receive web hooks, and act when such a trigger is received.

Just a few examples:

  • GitHub can send web hooks when something changes in a repo (in any repository you administer, go to "Settings" -> "Webhooks", and add your own hook)
  • Tasker for Android can send HTTP(s) requests
  • JIRA can send web hooks when certain events occur
  • openHAB can send messages to other services

Now it would be useful to have your own receiver for web hooks, and run any task you want. There are a number of tools out there, which can solve this problem. I settled with "webhook". In addition, I deploy everything using Ansible, therefore I had to write a bit of code in order to automate this process.

 

Let's start with installing "webhook":

- name: webhook packages
  apt: name={{ item }} state=present
  with_items:
    - webhook
    - python3-yaml
  register: webhook_install

Let's Encrypt requires that certificate renewal happens on port 80 (if you are using the HTTP-01 challenge mechanism). Doing the certificate renewal is beyond this blog post, there are several possible methods. Let's just assume there is another service running which renews the certificate every once in a while, and "webhook" has access to the certificate and can use it.

By default, webhook will not use encryption. But of course we want that. Encryption can be enabled using the "-secure" option, and providing the certificate (-cert option) and the key (-key option). Let's update everything in the systemd service file:

# update systemd service file for webhooks
# TLS certificate is Let's Encrypt
- name: /lib/systemd/system/webhook.service
  lineinfile:
    dest: /lib/systemd/system/webhook.service
    regexp: "{{ item.regexp }}"
    line: "{{ item.line }}"
    state: "{{ item.state }}"
  with_items:
    - { regexp: '^ExecStart', line: 'ExecStart=/usr/bin/webhook -nopanic -port 6500 -hotreload -verbose -hooks /etc/webhook.conf -secure -cert /etc/ssl/signed.crt -key /etc/ssl/domain.key', state: present }
  register: webhook_service

It also needs a webhook.conf, with the actual configuration of what you want to listen to:

- name: Upload webhook.conf
  template:
    src: webhook.conf
    dest: /etc/webhook.conf
    owner: root
    group: root
    mode: 0640
  register: etc_webhook_conf

Make sure (mode: 0640) that not everyone can read this file - most likely you have secrets configured in it. Documentation how to write a webhook config is here, examples are here.

The next part is a bit more tricky: although the above systemd service file specifies the "-hotreload" option, this only applies to changes in the webhooks.conf. webhook will not recognize when the certificate is renewed, and needs to be restarted for that. I'm using another systemd service for that - and because of the way systemd handles that, you need two files: the service file, and a file for the timer. Wasn't it easy when you just created a single line in a cron job?

webhook-restart.service:

[Unit]
Description=restart webhook

[Service]
Type=oneshot
ExecStart=/bin/systemctl restart webhook
TimeoutStopSec=900
KillMode=process

webhook-restart.timer:

[Timer]
OnCalendar=*-- 3:00:00
Persistent=true

[Install]
WantedBy=timers.target

Upload everything to the server:

- name: Upload webhook restart service
  template:
    src: containers/files/webhooks/webhook-restart.service
    dest: /etc/systemd/system/webhook-restart.service
    owner: root
    group: root
    mode: 0640
  register: webhook_restart_service


- name: Upload webhook restart timer
  template:
    src: containers/files/webhooks/webhook-restart.timer
    dest: /etc/systemd/system/webhook-restart.timer
    owner: root
    group: root
    mode: 0640
  register: webhook_restart_time

Enable and start the service and the timer:

# the service is not automatically registered and started
- name: enable webhook service
  service:
    name: webhook
    state: started
    enabled: yes
  when: webhook_install.changed


- name: enable webhook-restart service
  service:
    name: webhook-restart
    state: started
    enabled: yes


- name: enable webhook-restart timer
  service:
    name: webhook-restart.timer
    state: started
    enabled: yes

And if something has changed, systemd must be reloaded, and webhook must be restarted:

- name: force systemd to reread configs
  systemd:
    daemon_reload: yes
  when: webhook_service.changed or webhook_restart_service.changed or webhook_restart_time.changed


- name: restart webhook
  service:
    name: webhook
    state: restarted
  when: webhook_service.changed


- name: reload webhook service
  shell: killall -USR1 webhook
  when: etc_webhook_conf.changed

 

That's it. The webhook service is now up and running on port 6500. webhook itself does not do any host verification. It will just listen to any hostname which points to this server.

  • Twitter
  • Bookmark webhook service with TLS and Let's Encrypt certificate at del.icio.us
  • Facebook
  • Google Bookmarks
  • FriendFeed
  • Digg webhook service with TLS and Let's Encrypt certificate
  • Bloglines webhook service with TLS and Let's Encrypt certificate
  • Technorati webhook service with TLS and Let's Encrypt certificate
  • Fark this: webhook service with TLS and Let's Encrypt certificate
  • Bookmark webhook service with TLS and Let's Encrypt certificate at YahooMyWeb
  • Bookmark webhook service with TLS and Let's Encrypt certificate at Furl.net
  • Bookmark webhook service with TLS and Let's Encrypt certificate at reddit.com
  • Bookmark webhook service with TLS and Let's Encrypt certificate at blinklist.com
  • Bookmark webhook service with TLS and Let's Encrypt certificate at Spurl.net
  • Bookmark webhook service with TLS and Let's Encrypt certificate at Simpy.com
  • Bookmark webhook service with TLS and Let's Encrypt certificate at blogmarks
  • Bookmark webhook service with TLS and Let's Encrypt certificate with wists
  • wong it!
  • Bookmark using any bookmark manager!
  • Stumble It!
  • Identi.ca

Trackbacks

No Trackbacks

Comments

Display comments as Linear | Threaded

No comments

Add Comment

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.
To leave a comment you must approve it via e-mail, which will be sent to your address after submission.
Form options