Skip to content

Commit

Permalink
feat(work): add vpn_disconnect and provision sudo
Browse files Browse the repository at this point in the history
This was a fantastic exercise in sudoers syntax, new ansible modules
(blockinfile, copy, template) and general security considerations.

The openfortivpn process must be run as root, and so it can only be
killed by root. A simple pkill openfortivpn won't do: we need sudo. But
what if we're in a context where we can't supply the password - i.e.
clicking a polybar module? We'll have to add a script we can run with
passwordless sudo. But how do we manage this script? The usual linking
of an executable script to ~/.local/bin works, but...

First I thought enabling passwordless sudo for a symlink would have
security implications. What if the underlying script was changed? In the
end, that would probably not have worked, because sudo would have
evaluated the permissions for the target file and not the symlink. But
nevertheless, I set out to write a non-modifiable script, executable by
everyone and with passwordless sudo by members of the openfortivpn
group. This is the result. In the process, I also moved the manual steps
from the base/work README to topic.tasks.yml. The CLI will require some
updates to pass the 'sudo_enabled' tag.
  • Loading branch information
eliasnorrby committed Mar 6, 2021
1 parent a7d9c89 commit 00ff1d0
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 0 deletions.
6 changes: 6 additions & 0 deletions _provision/files/vpn_disconnect.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh

VPN_PID=$(pgrep -x openfortivpn)
if [ -n "$VPN_PID" ]; then
sudo kill -SIGINT "$VPN_PID"
fi
2 changes: 2 additions & 0 deletions base/work/topic.config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ work_config:
pacman_packages:
- openfortivpn

vpn_group_name: openfortivpn
vpn_disconnect_path: /usr/local/bin/vpn_disconnect
39 changes: 39 additions & 0 deletions base/work/topic.tasks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
- block:
- name: add vpn_disconnect script
copy:
src: files/vpn_disconnect.sh
dest: "{{ vpn_disconnect_path }}"
mode: '0755'
owner: root
group: root
- name: add vpn group
group:
name: "{{ vpn_group_name }}"
state: present
- name: add user to vpn group
user:
name: "{{ ansible_user_id }}"
groups: "{{ vpn_group_name }}"
append: yes
- name: enable passwordless sudo
blockinfile:
path: /etc/sudoers.d/12-vpn-control
block: |
Cmnd_Alias OPENFORTIVPN = /usr/bin/openfortivpn, {{ vpn_disconnect_path }}
%{{ vpn_group_name }} ALL=(ALL) NOPASSWD: OPENFORTIVPN
create: yes
validate: "visudo -cf %s"
become: yes
tags: ["never", "sudo_enabled"]

- name: notice about sudo
debug:
msg: |
The tasks for VPN require sudo and have been skipped.
Please pass the 'sudo_enabled' tag (use the --become flag for the CLI)
to run them.
when: "'sudo_enabled' not in ansible_run_tags"
tags: ["always"]

0 comments on commit 00ff1d0

Please sign in to comment.