Skip to content

Commit

Permalink
Persistent config on Qubes OS using debops.persistent_paths
Browse files Browse the repository at this point in the history
  • Loading branch information
ypid committed Mar 16, 2017
1 parent 98421f4 commit d5cb3ef
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 39 deletions.
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ Added
:command:`resolvconf` script when the network interfaces are configured
statically. [drybjed_]

- Support for persistent configuration of TemplateBasedVM on `Qubes OS`_ out of
the box using the debops.persistent_paths_ role. [ypid_]

Changed
~~~~~~~

Expand Down
6 changes: 3 additions & 3 deletions COPYRIGHT
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
debops.tinc - Configure tinc mesh VPN network

Copyright (C) 2015-2016 Maciej Delmanowski <[email protected]>
Copyright (C) 2016 Robin Schneider <[email protected]>
Copyright (C) 2015-2016 DebOps https://debops.org/
Copyright (C) 2015-2017 Maciej Delmanowski <[email protected]>
Copyright (C) 2016-2017 Robin Schneider <[email protected]>
Copyright (C) 2015-2017 DebOps https://debops.org/

This Ansible role is part of DebOps.

Expand Down
43 changes: 43 additions & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,20 @@ tinc__systemd: '{{ True
if (ansible_service_mgr|d("unknown") == "systemd")
else False }}'

# ]]]
# .. envvar:: tinc__persistent_prefix_path [[[
#
# Directory path prefix which should be used for writing/updating of files made
# persistent by :envvar:`tinc__persistent_paths__dependent_paths`.
tinc__persistent_prefix_path: '{{ ansible_local.persistent_paths.storage_path|d("")
if (ansible_local|d() and
ansible_local.tinc|d() and
ansible_local.tinc.enabled|d() | bool and
ansible_local.persistent_paths|d() and
ansible_local.persistent_paths.enabled|d() | bool and
ansible_local.persistent_paths.write_to_storage_path|d() | bool)
else "" }}'

# ]]]
# .. envvar:: tinc__vcs_ignore_patterns [[[
#
Expand Down Expand Up @@ -301,6 +315,35 @@ tinc__etc_services__dependent_list: '{{ lookup("template",
tinc__ferm__dependent_rules: '{{ lookup("template",
"lookup/tinc__ferm__dependent_rules.j2",
convert_data=False) | from_yaml }}'

# ]]]
# .. envvar:: tinc__persistent_paths__dependent_paths [[[
#
# Configuration for the debops.persistent_paths_ Ansible role.
tinc__persistent_paths__dependent_paths:

'50_debops_tinc':
by_role: 'debops.tinc'
paths: |
{{ [
'/etc/tinc',
'/etc/systemd/system/tinc.service',
'/etc/systemd/system/[email protected]',
'/etc/systemd/system/multi-user.target.wants/tinc.service',
] + ((ansible_local.tinc.networks.keys() | map("regex_replace", "^", "/etc/default/tinc-") | list)
if (ansible_local|d() and ansible_local.tinc|d() and
ansible_local.tinc.networks|d())
else [])
}}
## Note that when the same network gets deleted and then added again to
## `tinc__combined_networks`, the role might need two runs to also update
## the defaults file in the persistent location.
## '/etc/systemd/system/multi-user.target.wants/tinc.service':
## Note that bind-dirs in Qubes OS currently does not restore symlinks (only their destination).
## This works for ypid_ as he does not want auto start on Qubes OS AppVMs anyway.
## If you need it on Qubes OS, feel free to discuss and patch bind-dirs.
# ]]]
# ]]]
# ]]]
35 changes: 34 additions & 1 deletion docs/getting-started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,13 @@ generated from templates to other roles.
If you are using this role without DebOps, here's an example Ansible playbook
that uses the ``debops.tinc`` role:

.. literalinclude:: playbooks/tinc.yml
.. literalinclude:: playbooks/tinc-plain.yml
:language: yaml

If you are using this role without DebOps, here's an example Ansible playbook
that uses ``debops.tinc`` together with the debops.persistent_paths_ role:

.. literalinclude:: playbooks/tinc-persistent_paths.yml
:language: yaml

Static vs DHCP connection type
Expand Down Expand Up @@ -196,3 +202,30 @@ commands:
systemctl status tinc@mesh0
systemctl start tinc@mesh0
systemctl stop tinc@mesh0
debops.persistent_paths_ support
--------------------------------

In case the host in question happens to be a TemplateBasedVM on `Qubes OS`_ or
another system where persistence is not the default, it should absent in
``debops_service_tinc`` and instead be added to
``debops_service_tinc_persistent_paths`` so that the changes can be made
persistently:

.. code:: ini
[debops_service_tinc_persistent_paths]
hostname
Note that the :envvar:`tinc__user` (``tinc-vpn`` by default) created by the role is not made persistent because making
:file:`/etc/passwd` and related files persistent might interfere with template
changes.

You will need to ensure that the user exists by one of the following ways:

* Create the user in the template using :command:`useradd --system tinc-vpn --comment 'tinc VPN service' --home-dir '/etc/tinc' --shell '/bin/false'`
* Running the above command on start in the TemplateBasedVM
* Run the role against your template with the role configured in such a way that it only
creates the user. Note that this is normally `discouraged <https://www.qubes-os.org/doc/software-update-vm/#notes-on-trusting-your-templatevms>`_.

Besides that, the :envvar:`tinc__base_packages` are expected to be present (typically installed in the TemplateVM).
37 changes: 37 additions & 0 deletions docs/playbooks/tinc-persistent_paths.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---

- name: Configure Tinc VPN and ensure persistence
hosts: [ 'debops_service_tinc_persistent_paths', 'debops_service_tinc_aux' ]
become: True

environment: '{{ inventory__environment | d({})
| combine(inventory__group_environment | d({}))
| combine(inventory__host_environment | d({})) }}'

roles:

- role: debops.tinc/env
tags: [ 'role::tinc', 'role::tinc:secret', 'role::secret', 'role::ferm' ]

- role: debops.secret
tags: [ 'role::secret', 'role::tinc:secret' ]
secret_directories: '{{ tinc__env_secret__directories }}'

- role: debops.apt_preferences
tags: [ 'role::apt_preferences' ]
apt_preferences__dependent_list: '{{ tinc__apt_preferences__dependent_list }}'

- role: debops.etc_services
tags: [ 'role::etc_services' ]
etc_services__dependent_list: '{{ tinc__env_etc_services__dependent_list }}'

- role: debops.ferm
tags: [ 'role::ferm' ]
ferm__dependent_rules: '{{ tinc__env_ferm__dependent_rules }}'

- role: debops.tinc
tags: [ 'role::tinc' ]

- role: debops.persistent_paths
tags: [ 'role::persistent_paths' ]
persistent_paths__dependent_paths: '{{ tinc__persistent_paths__dependent_paths }}'
33 changes: 33 additions & 0 deletions docs/playbooks/tinc-plain.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---

- name: Configure Tinc VPN
hosts: [ 'debops_service_tinc', 'debops_service_tinc_aux' ]
become: True

environment: '{{ inventory__environment | d({})
| combine(inventory__group_environment | d({}))
| combine(inventory__host_environment | d({})) }}'

roles:

- role: debops.tinc/env
tags: [ 'role::tinc', 'role::tinc:secret', 'role::secret', 'role::ferm' ]

- role: debops.secret
tags: [ 'role::secret', 'role::tinc:secret' ]
secret_directories: '{{ tinc__env_secret__directories }}'

- role: debops.apt_preferences
tags: [ 'role::apt_preferences' ]
apt_preferences__dependent_list: '{{ tinc__apt_preferences__dependent_list }}'

- role: debops.etc_services
tags: [ 'role::etc_services' ]
etc_services__dependent_list: '{{ tinc__env_etc_services__dependent_list }}'

- role: debops.ferm
tags: [ 'role::ferm' ]
ferm__dependent_rules: '{{ tinc__env_ferm__dependent_rules }}'

- role: debops.tinc
tags: [ 'role::tinc' ]
32 changes: 2 additions & 30 deletions docs/playbooks/tinc.yml
Original file line number Diff line number Diff line change
@@ -1,33 +1,5 @@
---

- name: Configure Tinc VPN
hosts: [ 'debops_service_tinc', 'debops_service_tinc_aux' ]
become: True
- include: tinc-plain.yml

environment: '{{ inventory__environment | d({})
| combine(inventory__group_environment | d({}))
| combine(inventory__host_environment | d({})) }}'

roles:

- role: debops.tinc/env
tags: [ 'role::tinc', 'role::tinc:secret', 'role::secret', 'role::ferm' ]

- role: debops.secret
tags: [ 'role::secret', 'role::tinc:secret' ]
secret_directories: '{{ tinc__env_secret__directories }}'

- role: debops.apt_preferences
tags: [ 'role::apt_preferences' ]
apt_preferences__dependent_list: '{{ tinc__apt_preferences__dependent_list }}'

- role: debops.etc_services
tags: [ 'role::etc_services' ]
etc_services__dependent_list: '{{ tinc__env_etc_services__dependent_list }}'

- role: debops.ferm
tags: [ 'role::ferm' ]
ferm__dependent_rules: '{{ tinc__env_ferm__dependent_rules }}'

- role: debops.tinc
tags: [ 'role::tinc' ]
- include: tinc-persistent_paths.yml
38 changes: 33 additions & 5 deletions tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@
group: 'root'
mode: '0644'

## RSA key management [[[1
# RSA key management [[[1

- name: Ensure that sensitive files are excluded from version control
template:
Expand All @@ -157,7 +157,7 @@
with_dict: '{{ tinc__combined_networks }}'
when: item.value.state|d('present') != 'absent'

## Tinc host configuration [[[1
# Tinc host configuration [[[1
- name: Generate host configuration file
template:
src: 'etc/tinc/network/hosts/host-config.j2'
Expand All @@ -179,7 +179,7 @@
when: item.value.state|d('present') != 'absent'
notify: [ 'Reload tinc' ]

## Tinc host configuration distribution [[[1
# Tinc host configuration distribution [[[1
- name: Upload public keys from hosts to Ansible Controller
fetch:
src: '/etc/tinc/{{ item.value.name | d(item.key) }}/hosts/{{ (item.value.hostname | d(tinc__hostname)) | replace("-","_") }}'
Expand Down Expand Up @@ -235,7 +235,7 @@
when: item.value.state|d('present') != 'absent'
notify: [ 'Reload tinc' ]

## systemd configuration [[[1
# systemd configuration [[[1
- name: Configure systemd default variables
template:
src: 'etc/default/tinc-network.j2'
Expand Down Expand Up @@ -264,7 +264,7 @@
- name: Configure systemd unit files
template:
src: 'etc/systemd/system/{{ item }}.j2'
dest: '/etc/systemd/system/{{ item }}'
dest: '{{ tinc__persistent_prefix_path + "/" + item }}'
owner: 'root'
group: 'root'
mode: '0644'
Expand All @@ -290,3 +290,31 @@
with_dict: '{{ tinc__combined_networks }}'
when: tinc__systemd|bool and item.value.state|d('present') != 'absent' and
item.value.port|d()

# Ansible facts [[[1

# Note that for ``debops.persistent_paths`` on Qubes OS to work correctly, the
# facts need to be generated at the end of the (first) role playbook run. Note
# this if it might be necessary to move this to a separate env role. Not sure
# yet how this could be handled to cover both cases.

- name: Make sure Ansible fact directory exists
file:
path: '/etc/ansible/facts.d'
state: 'directory'
owner: 'root'
group: 'root'
mode: '0755'

- name: Create local facts of tinc
template:
src: 'etc/ansible/facts.d/tinc.fact.j2'
dest: '/etc/ansible/facts.d/tinc.fact'
owner: 'root'
group: 'root'
mode: '0644'
register: tinc__register_facts

- name: Reload facts if they were modified
action: setup
when: tinc__register_facts|changed
4 changes: 4 additions & 0 deletions templates/etc/ansible/facts.d/tinc.fact.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{{ ({
"enabled": True,
"networks": tinc__combined_networks,
}) | to_nice_json }}

0 comments on commit d5cb3ef

Please sign in to comment.