commit f17e5de557eb1224245245a0c4ac25aa2941de83 Author: Jan Christian Grünhage Date: Mon Dec 17 14:19:59 2018 +0100 initial commit diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..485e376 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,6 @@ +root = true + +[*.yml] +insert_final_newline = true +indent_style = space +indent_size = 2 diff --git a/README.md b/README.md new file mode 100644 index 0000000..e946dae --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +yggdrasil +========= + +Deploy yggdrasil using Ansible. + +Dependencies +------------ + +ansible_lsb needs additional packages on some systems, +those need to be available + + +Role Variables +-------------- + +For available variables take a look at the config template, +it is currently the only place with variables. + +Example Playbook +---------------- + + - hosts: servers + roles: + - role: yggdrasil + become: yes + +License +------- + +AGPLv3 + +Author Information +------------------ + +Jan Christian Grünhage diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..68bbf00 --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,8 @@ +--- +# defaults file for yggdrasil +yggdrasil_listen_address: "[::]:61216" +yggdrasil_admin_listen_address: "unix:///var/run/yggdrasil.sock" +yggdrasil_peers: [] +yggdrasil_interface_peer_interfaces: [] +yggdrasil_allowed_encryption_public_keys: [] +yggdrasil_multicast_interfaces: [ ".*" ] diff --git a/files/fedora/yggdrasil.repo b/files/fedora/yggdrasil.repo new file mode 100644 index 0000000..83750a7 --- /dev/null +++ b/files/fedora/yggdrasil.repo @@ -0,0 +1,4 @@ +[yggdrasil] +name = Yggdrasil +baseurl = https://neilalexander.s3.eu-west-2.amazonaws.com/rpm/ +gpgcheck=1 diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..cd36d22 --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,17 @@ +--- +# handlers file for yggdrasil +- name: restart yggdrasil using service + service: + name: yggdrasil + enabled: true + state: restarted + when: ansible_lsb.id is not "Void" + listen: restart yggdrasil + +- name: restart yggdrasil using runit + runit: + name: yggdrasil + enabled: true + state: restarted + when: ansible_lsb.id is "Void" + listen: restart yggdrasil diff --git a/meta/main.yml b/meta/main.yml new file mode 100644 index 0000000..47fbcfb --- /dev/null +++ b/meta/main.yml @@ -0,0 +1,12 @@ +--- +galaxy_info: + author: Jan Christian Grünhage + description: Install and configure yggdrasil + + license: AGPLv3 + + min_ansible_version: 2.5 + + galaxy_tags: [] + +dependencies: [] diff --git a/tasks/configure.yml b/tasks/configure.yml new file mode 100644 index 0000000..cdd8bed --- /dev/null +++ b/tasks/configure.yml @@ -0,0 +1,3 @@ +--- +- import_tasks: configure/configuration.yml +- import_tasks: configure/service.yml diff --git a/tasks/configure/configuration.yml b/tasks/configure/configuration.yml new file mode 100644 index 0000000..85bde5d --- /dev/null +++ b/tasks/configure/configuration.yml @@ -0,0 +1,6 @@ +--- +- name: template configuration + template: + src: yggdrasil.conf.j2 + dest: /etc/yggdrasil.conf + notify: restart yggdrasil diff --git a/tasks/configure/service.yml b/tasks/configure/service.yml new file mode 100644 index 0000000..5c5cce8 --- /dev/null +++ b/tasks/configure/service.yml @@ -0,0 +1,16 @@ +--- +- name: start yggdrasil + service: + name: yggdrasil + enabled: true + state: started + when: ansible_lsb.id is not "Void" + +# This separate entry here is needed because +# the service module does not support runit +- name: start yggdrasil + runit: + name: yggdrasil + enabled: true + state: started + when: ansible_lsb.id is "Void" diff --git a/tasks/install.yml b/tasks/install.yml new file mode 100644 index 0000000..e3021d2 --- /dev/null +++ b/tasks/install.yml @@ -0,0 +1,11 @@ +--- +- import_tasks: install/void.yml + when: ansible_lsb.id is "VoidLinux" + +- import_tasks: install/fedora.yml + when: ansible_lsb.id is "Fedora" or ansible_lsb.id is "CentOS" + +- import_tasks: install/debian.yml + when: ansible_lsb.id is "Debian" or ansible_lsb.id is "Ubuntu" + +# TODO: Support more distros (and maybe even Windows one day) diff --git a/tasks/install/debian.yml b/tasks/install/debian.yml new file mode 100644 index 0000000..6a1e473 --- /dev/null +++ b/tasks/install/debian.yml @@ -0,0 +1,15 @@ +--- +- name: add apt key + apt_key: + state: present + keyserver: pool.sks-keyservers.net + id: 569130E8CA20FBC4CB3FDE555898470A764B32C9 + +- name: add apt repository + apt_repository: + repo: deb http://neilalexander.s3.eu-west-2.amazonaws.com/deb/ debian yggdrasil + state: present + +- name: install yggdrasil + apt: + name: yggdrasil diff --git a/tasks/install/fedora.yml b/tasks/install/fedora.yml new file mode 100644 index 0000000..dd0e41d --- /dev/null +++ b/tasks/install/fedora.yml @@ -0,0 +1,21 @@ +--- +- name: add rpm key + rpm_key: + key: http://pool.sks-keyservers.net/pks/lookup?op=get&search=0x5898470A764B32C9 + +- name: add yum repo + copy: + src: fedora/yggdrasil.repo + dest: /etc/yum.repos.d/yggdrasil.repo + owner: root + group: root + +- name: install yggdrasil + dnf: + name: yggdrasil + when: ansible_lsb.id is "Fedora" + +- name: install yggdrasil + yum: + name: yggdrasil + when: ansible_lsb.id is not "Fedora" diff --git a/tasks/install/void.yml b/tasks/install/void.yml new file mode 100644 index 0000000..68fbdc6 --- /dev/null +++ b/tasks/install/void.yml @@ -0,0 +1,7 @@ +--- +- name: install yggdrasil + xbps: + name: "{{ package }}" + loop: + - yggdrasil + - yggdrasilctl diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..0171113 --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,3 @@ +--- +- import_tasks: install.yml +- import_tasks: configure.yml diff --git a/templates/yggdrasil.conf.j2 b/templates/yggdrasil.conf.j2 new file mode 100644 index 0000000..b1b334d --- /dev/null +++ b/templates/yggdrasil.conf.j2 @@ -0,0 +1,153 @@ +{ + # Listen address for peer connections. Default is to listen for all + # TCP connections over IPv4 and IPv6 with a random port. + Listen: "{{ yggdrasil_listen_address }}" + + # Listen address for admin connections. Default is to listen for local + # connections either on TCP/9001 or a UNIX socket depending on your + # platform. Use this value for yggdrasilctl -endpoint=X. To disable + # the admin socket, use the value "none" instead. + AdminListen: "{{ yggdrasil_admin_listen_address }}" + + # List of connection strings for static peers in URI format, e.g. + # tcp://a.b.c.d:e or socks://a.b.c.d:e/f.g.h.i:j. + Peers: [ + {% for peer in yggdrasil_peers %} + "{{ peer }}", + {% endfor %} + ] + + # List of connection strings for static peers in URI format, arranged + # by source interface, e.g. { "eth0": [ tcp://a.b.c.d:e ] }. Note that + # SOCKS peerings will NOT be affected by this option and should go in + # the "Peers" section instead. + InterfacePeers: { + {% for interface in yggdrasil_interface_peer_interfaces %} + {{ interface.identifier }}: [ + {% for peer in interface.peers %} + "{{ peer }}", + {% endfor %} + ], + {% endfor %} + } + + # Read timeout for connections, specified in milliseconds. If less + # than 6000 and not negative, 6000 (the default) is used. If negative, + # reads won't time out. + ReadTimeout: 0 + + # List of peer encryption public keys to allow or incoming TCP + # connections from. If left empty/undefined then all connections + # will be allowed by default. + AllowedEncryptionPublicKeys: [ + {% for key in yggdrasil_allowed_encryption_keys %} + "{{ key }}", + {% endfor %} + ] + + # Your public encryption key. Your peers may ask you for this to put + # into their AllowedEncryptionPublicKeys configuration. + EncryptionPublicKey: "{{ yggdrasil_encryption_public_key }}" + + # Your private encryption key. DO NOT share this with anyone! + EncryptionPrivateKey: "{{ yggdrasil_encryption_private_key }}" + + # Your public signing key. You should not ordinarily need to share + # this with anyone. + SigningPublicKey: "{{ yggdrasil_signing_public_key }}" + + # Your private signing key. DO NOT share this with anyone! + SigningPrivateKey: "{{ yggdrasil_signing_private_key }}" + + # Regular expressions for which interfaces multicast peer discovery + # should be enabled on. If none specified, multicast peer discovery is + # disabled. The default value is .* which uses all interfaces. + MulticastInterfaces: + [ + {% for interface in yggdrasil_multicast_interfaces %} + {{ interface }} + {% endfor %} + ] + + # Local network interface name for TUN/TAP adapter, or "auto" to select + # an interface automatically, or "none" to run without TUN/TAP. + IfName: auto + + # Set local network interface to TAP mode rather than TUN mode if + # supported by your platform - option will be ignored if not. + IfTAPMode: false + + # Maximux Transmission Unit (MTU) size for your local TUN/TAP interface. + # Default is the largest supported size for your platform. The lowest + # possible value is 1280. + IfMTU: 65535 + + # The session firewall controls who can send/receive network traffic + # to/from. This is useful if you want to protect this node without + # resorting to using a real firewall. This does not affect traffic + # being routed via this node to somewhere else. Rules are prioritised as + # follows: blacklist, whitelist, always allow outgoing, direct, remote. + SessionFirewall: + { + # Enable or disable the session firewall. If disabled, network traffic + # from any node will be allowed. If enabled, the below rules apply. + Enable: false + + # Allow network traffic from directly connected peers. + AllowFromDirect: true + + # Allow network traffic from remote nodes on the network that you are + # not directly peered with. + AllowFromRemote: true + + # Allow outbound network traffic regardless of AllowFromDirect or + # AllowFromRemote. This does allow a remote node to send unsolicited + # traffic back to you for the length of the session. + AlwaysAllowOutbound: false + + # List of public keys from which network traffic is always accepted, + # regardless of AllowFromDirect or AllowFromRemote. + WhitelistEncryptionPublicKeys: [] + + # List of public keys from which network traffic is always rejected, + # regardless of the whitelist, AllowFromDirect or AllowFromRemote. + BlacklistEncryptionPublicKeys: [] + } + + # Allow tunneling non-Yggdrasil traffic over Yggdrasil. This effectively + # allows you to use Yggdrasil to route to, or to bridge other networks, + # similar to a VPN tunnel. Tunnelling works between any two nodes and + # does not require them to be directly peered. + TunnelRouting: + { + # Enable or disable tunnel routing. + Enable: false + + # IPv6 CIDR subnets, mapped to the EncryptionPublicKey to which they + # should be routed, e.g. { "aaaa:bbbb:cccc::/e": "boxpubkey", ... } + IPv6Destinations: {} + + # Optional IPv6 source subnets which are allowed to be tunnelled in + # addition to this node's Yggdrasil address/subnet. If not + # specified, only traffic originating from this node's Yggdrasil + # address or subnet will be tunnelled. + IPv6Sources: [] + + # IPv4 CIDR subnets, mapped to the EncryptionPublicKey to which they + # should be routed, e.g. { "a.b.c.d/e": "boxpubkey", ... } + IPv4Destinations: {} + + # IPv4 source subnets which are allowed to be tunnelled. Unlike for + # IPv6, this option is required for bridging IPv4 traffic. Only + # traffic with a source matching these subnets will be tunnelled. + IPv4Sources: [] + } + + # Advanced options for tuning the switch. Normally you will not need + # to edit these options. + SwitchOptions: + { + # Maximum size of all switch queues combined (in bytes). + MaxTotalQueueSize: 4194304 + } +} diff --git a/vars/main.yml b/vars/main.yml new file mode 100644 index 0000000..3162683 --- /dev/null +++ b/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for yggdrasil