From 22e275c7b60614196c2d7563a5199144036a4347 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Sat, 22 Dec 2018 03:25:25 +0100 Subject: added openwrt role and config for elevate router --- dan/ele-router.yml | 6 + files/common/htoprc | 26 ++++ inventory/host_vars/ele-router.yml | 210 ++++++++++++++++++++++++++++++++ inventory/hosts.ini | 4 +- roles/base/files/htoprc | 26 ---- roles/base/tasks/main.yml | 2 +- roles/openwrt/image/README.md | 8 ++ roles/openwrt/image/defaults/main.yml | 17 +++ roles/openwrt/image/openwrt-keyring.gpg | Bin 0 -> 2378 bytes roles/openwrt/image/tasks/fetch.yml | 52 ++++++++ roles/openwrt/image/tasks/main.yml | 38 ++++++ roles/openwrt/image/tasks/prepare.yml | 95 +++++++++++++++ roles/openwrt/image/templates/group.j2 | 21 ++++ roles/openwrt/image/templates/passwd.j2 | 9 ++ roles/openwrt/image/templates/uci.j2 | 15 +++ 15 files changed, 500 insertions(+), 29 deletions(-) create mode 100644 dan/ele-router.yml create mode 100644 files/common/htoprc create mode 100644 inventory/host_vars/ele-router.yml delete mode 100644 roles/base/files/htoprc create mode 100644 roles/openwrt/image/README.md create mode 100644 roles/openwrt/image/defaults/main.yml create mode 100644 roles/openwrt/image/openwrt-keyring.gpg create mode 100644 roles/openwrt/image/tasks/fetch.yml create mode 100644 roles/openwrt/image/tasks/main.yml create mode 100644 roles/openwrt/image/tasks/prepare.yml create mode 100644 roles/openwrt/image/templates/group.j2 create mode 100644 roles/openwrt/image/templates/passwd.j2 create mode 100644 roles/openwrt/image/templates/uci.j2 diff --git a/dan/ele-router.yml b/dan/ele-router.yml new file mode 100644 index 00000000..4f3d1ceb --- /dev/null +++ b/dan/ele-router.yml @@ -0,0 +1,6 @@ +--- +- hosts: ele-router + connection: local + roles: + - role: openwrt/image + delegate_to: localhost diff --git a/files/common/htoprc b/files/common/htoprc new file mode 100644 index 00000000..41add184 --- /dev/null +++ b/files/common/htoprc @@ -0,0 +1,26 @@ +# Beware! This file is rewritten by htop when settings are changed in the interface. +# The parser is also very primitive, and not human-friendly. +fields=0 48 17 18 38 39 40 2 46 47 49 1 +sort_key=46 +sort_direction=1 +hide_threads=0 +hide_kernel_threads=1 +hide_userland_threads=1 +shadow_other_users=0 +show_thread_names=0 +show_program_path=1 +highlight_base_name=1 +highlight_megabytes=1 +highlight_threads=1 +tree_view=1 +header_margin=1 +detailed_cpu_time=0 +cpu_count_from_zero=0 +update_process_names=0 +account_guest_in_cpu_meter=0 +color_scheme=0 +delay=15 +left_meters=LeftCPUs Memory Swap +left_meter_modes=1 1 1 +right_meters=RightCPUs Tasks LoadAverage Uptime +right_meter_modes=1 2 2 2 diff --git a/inventory/host_vars/ele-router.yml b/inventory/host_vars/ele-router.yml new file mode 100644 index 00000000..8b92a94f --- /dev/null +++ b/inventory/host_vars/ele-router.yml @@ -0,0 +1,210 @@ +--- +openwrt_variant: lede +openwrt_release: 17.01.6 +openwrt_arch: ar71xx +openwrt_target: generic +openwrt_profile: tl-wr710n-v2 +openwrt_output_image_suffixes: + - "generic-{{ openwrt_profile }}-squashfs-sysupgrade.bin" + +openwrt_packages_remove: + - kmod-gpio-button-hotplug + - kmod-ath9k + - wpad-mini + - ppp + - ppp-mod-pppoe + - firewall + - odhcpd-ipv6only +openwrt_packages_add: + - kmod-ipt-nat + - haveged + - htop + - ip + - less + - nano + - tcpdump-mini + - iperf + - mtr + - qos-scripts + + +openwrt_mixin: + /etc/dropbear/authorized_keys: + content: "{{ ssh_keys_root | join('\n') }}\n" + + /etc/htoprc: + file: "{{ global_files_dir }}/common/htoprc" + + ## TODO: this needs to be activated... + /etc/init.d/network-nat: + mode: "0755" + content: | + #!/bin/sh /etc/rc.common + + START=22 + STOP=90 + + source /lib/functions/network.sh + + network_get_device WAN_IF "wan" + + network_get_subnets LAN_NETS "lan" + network_get_subnets GUEST_NETS "guest" + network_get_subnets INFO_NETS "infobeamer" + + start() { + for net in $LAN_NETS $GUEST_NETS $INFO_NETS; do + iptables -t nat -A POSTROUTING -o $WAN_IF -s $net -j MASQUERADE + done; + } + + stop() { + iptables -t nat POSTROUTING -F + } + + +openwrt_uci: + system: + - name: system + options: + hostname: '{{ inventory_hostname }}' + timezone: 'CET-1CEST,M3.5.0,M10.5.0/3' + ttylogin: '0' + log_size: '64' + urandom_seed: '0' + + - name: timeserver 'ntp' + options: + enabled: '1' + enable_server: '0' + server: + - '0.lede.pool.ntp.org' + - '1.lede.pool.ntp.org' + - '2.lede.pool.ntp.org' + - '3.lede.pool.ntp.org' + + dropbear: + - name: dropbear + options: + PasswordAuth: 'off' + RootPasswordAuth: 'off' + Port: '22000' + + dhcp: + - name: dnsmasq + options: + domainneeded: '1' + boguspriv: '1' + filterwin2k: '0' + localise_queries: '1' + rebind_protection: '1' + rebind_localhost: '1' + local: '/lan/' + domain: 'lan' + expandhosts: '1' + nonegcache: '0' + authoritative: '1' + readethers: '1' + leasefile: '/tmp/dhcp.leases' + resolvfile: '/tmp/resolv.conf.auto' + localservice: '1' + + - name: odhcpd 'odhcpd' + options: + maindhcp: '0' + leasefile: '/tmp/hosts/odhcpd' + leasetrigger: '/usr/sbin/odhcpd-update' + + - name: dhcp 'mgmt' + options: + interface: 'mgmt' + ignore: '1' + + - name: dhcp 'lan' + options: + interface: 'lan' + start: '1' + limit: '199' + leasetime: '12h' + dhcpv6: 'disabled' + ra: 'disabled' + + - name: dhcp 'guest' + options: + interface: 'guest' + start: '1' + limit: '199' + leasetime: '12h' + dhcpv6: 'disabled' + ra: 'disabled' + + - name: dhcp 'infobeamer' + options: + interface: 'infobeamer' + start: '100' + limit: '199' + leasetime: '12h' + dhcpv6: 'disabled' + ra: 'disabled' + + + network: + - name: globals 'globals' + options: + ula_prefix: fdc9:e01f:83db::/48 + + - name: interface 'loopback' + options: + ifname: lo + proto: static + ipaddr: 127.0.0.1 + netmask: 255.0.0.0 + + - name: interface 'wan' + options: + ifname: eth0 + proto: dhcp + + # - name: interface 'wan' + # options: + # ifname: eth0.91 + # accept_ra: 0 + # proto: static + # ipaddr: 85.237.28.228 + # netmask: 255.255.255.240 + # gateway: 85.237.28.225 + # dns: + # - 217.19.144.65 + # - 217.19.144.66 + + - name: interface 'mgmt' + options: + ifname: eth1.42 + accept_ra: 0 + proto: static + ipaddr: 192.168.42.254 + netmask: 255.255.255.0 + + - name: interface 'lan' + options: + ifname: eth1.18 + accept_ra: 0 + proto: static + ipaddr: 192.168.18.254 + netmask: 255.255.255.0 + + - name: interface 'guest' + options: + ifname: eth1.23 + accept_ra: 0 + proto: static + ipaddr: 192.168.23.254 + netmask: 255.255.255.0 + + - name: interface 'infobeamer' + options: + ifname: eth1.73 + accept_ra: 0 + proto: static + ipaddr: 192.168.73.254 + netmask: 255.255.255.0 diff --git a/inventory/hosts.ini b/inventory/hosts.ini index e177ddce..769b97b3 100644 --- a/inventory/hosts.ini +++ b/inventory/hosts.ini @@ -78,8 +78,8 @@ host_domain=elevate.at env_group=dan [elevate] -elemedia host_name=media - +ele-media host_name=media +ele-router ############################### # host categories diff --git a/roles/base/files/htoprc b/roles/base/files/htoprc deleted file mode 100644 index 41add184..00000000 --- a/roles/base/files/htoprc +++ /dev/null @@ -1,26 +0,0 @@ -# Beware! This file is rewritten by htop when settings are changed in the interface. -# The parser is also very primitive, and not human-friendly. -fields=0 48 17 18 38 39 40 2 46 47 49 1 -sort_key=46 -sort_direction=1 -hide_threads=0 -hide_kernel_threads=1 -hide_userland_threads=1 -shadow_other_users=0 -show_thread_names=0 -show_program_path=1 -highlight_base_name=1 -highlight_megabytes=1 -highlight_threads=1 -tree_view=1 -header_margin=1 -detailed_cpu_time=0 -cpu_count_from_zero=0 -update_process_names=0 -account_guest_in_cpu_meter=0 -color_scheme=0 -delay=15 -left_meters=LeftCPUs Memory Swap -left_meter_modes=1 1 1 -right_meters=RightCPUs Tasks LoadAverage Uptime -right_meter_modes=1 2 2 2 diff --git a/roles/base/tasks/main.yml b/roles/base/tasks/main.yml index f30cad66..767fd7fa 100644 --- a/roles/base/tasks/main.yml +++ b/roles/base/tasks/main.yml @@ -53,7 +53,7 @@ - /root - /etc/skel copy: - src: htoprc + src: "{{ global_files_dir }}/common/htoprc" dest: "{{ item }}/.config/htop/" - name: Ensure /root is not world accessible diff --git a/roles/openwrt/image/README.md b/roles/openwrt/image/README.md new file mode 100644 index 00000000..95d9d106 --- /dev/null +++ b/roles/openwrt/image/README.md @@ -0,0 +1,8 @@ +# Build OpenWRT images with Ansible + +TODO: add possibility to disable root logins using /etc/shadow + this will also take care of the annoying + "There is no root password defined ..." + message when you log in. + +## Configuration diff --git a/roles/openwrt/image/defaults/main.yml b/roles/openwrt/image/defaults/main.yml new file mode 100644 index 00000000..f00a2e80 --- /dev/null +++ b/roles/openwrt/image/defaults/main.yml @@ -0,0 +1,17 @@ +--- +openwrt_variant: lede +openwrt_release: 17.01.4 +openwrt_download_dir: "{{ global_cache_dir }}/openwrt" +openwrt_tarball_basename: "{{ openwrt_variant }}-imagebuilder-{{ openwrt_release }}-{{ openwrt_arch }}-{{ openwrt_target }}.Linux-x86_64" +openwrt_tarball_name: "{{ openwrt_tarball_basename }}.tar.xz" +openwrt_target: generic + +openwrt_output_dir: "{{ global_artifacts_dir }}/{{ inventory_hostname }}/openwrt" +openwrt_output_image_name_base: "{{ openwrt_variant }}-{{ openwrt_release }}-{{ openwrt_arch }}{% if openwrt_target != 'generic' %}-{{ openwrt_target }}{% endif %}" +openwrt_output_image_suffixes: + - squashfs-sysupgrade.bin + - squashfs-factory.bin + +openwrt_packages_remove: [] +openwrt_packages_add: [] +openwrt_packages_extra: [] diff --git a/roles/openwrt/image/openwrt-keyring.gpg b/roles/openwrt/image/openwrt-keyring.gpg new file mode 100644 index 00000000..e8a3e8b9 Binary files /dev/null and b/roles/openwrt/image/openwrt-keyring.gpg differ diff --git a/roles/openwrt/image/tasks/fetch.yml b/roles/openwrt/image/tasks/fetch.yml new file mode 100644 index 00000000..f68c87db --- /dev/null +++ b/roles/openwrt/image/tasks/fetch.yml @@ -0,0 +1,52 @@ +--- +- name: Create download directory + file: + dest: "{{ openwrt_download_dir }}" + state: directory + +- block: + - name: Generate OpenWrt download URLs + set_fact: + openwrt_url: + https://downloads.openwrt.org/releases/{{ openwrt_release }}/targets/{{ openwrt_arch | mandatory }}/{{ openwrt_target }} + + - name: Download sha256sums + get_url: + url: "{{ openwrt_url }}/sha256sums" + dest: "{{ openwrt_download_dir }}/{{ openwrt_tarball_basename }}.sha256" + + - name: Download sha256sums.asc + get_url: + url: "{{ openwrt_url }}/sha256sums.asc" + dest: "{{ openwrt_download_dir }}/{{ openwrt_tarball_basename }}.sha256.asc" + + - name: Check OpenPGP signature + command: >- + gpg2 --no-options --no-default-keyring --secret-keyring /dev/null + --verify --keyring "{{ role_path }}/openwrt-keyring.gpg" + --trust-model always + "{{ openwrt_download_dir }}/{{ openwrt_tarball_basename }}.sha256.asc" + changed_when: False + + - name: Extract SHA256 hash of the imagebuilder archive + command: grep '{{ openwrt_tarball_name }}' "{{ openwrt_download_dir }}/{{ openwrt_tarball_basename }}.sha256" + register: sha256 + changed_when: False + + - name: Download imagebuilder + get_url: + url: "{{ openwrt_url }}/{{ openwrt_tarball_name }}" + dest: "{{ openwrt_download_dir }}/{{ openwrt_tarball_name }}" + checksum: sha256:{{ sha256.stdout.split(' ') | first }} + + rescue: + - name: Delete downloaded artifacts + file: + path: "{{ item }}" + state: absent + with_items: + - "{{ openwrt_download_dir }}/{{ openwrt_tarball_basename }}.sha256" + - "{{ openwrt_download_dir }}/{{ openwrt_tarball_basename }}.sha256.asc" + - "{{ openwrt_download_dir }}/{{ openwrt_tarball_name }}" + - fail: + msg: Something borked diff --git a/roles/openwrt/image/tasks/main.yml b/roles/openwrt/image/tasks/main.yml new file mode 100644 index 00000000..1781d9ee --- /dev/null +++ b/roles/openwrt/image/tasks/main.yml @@ -0,0 +1,38 @@ +--- +- include: fetch.yml + run_once: true + when: openwrt_imgbuilder_tarball is not defined + +- block: + - include: prepare.yml + + - name: Create the output directory for built images + file: + path: "{{ openwrt_output_dir }}" + state: directory + + - set_fact: + openwrt_packages: >- + {{ openwrt_packages_remove | map('regex_replace', '^', '-') | join(' ') }} + {{ openwrt_packages_add | join(' ') }} + {{ openwrt_packages_extra | join(' ') }} + + - name: Build the OpenWrt image + command: >- + make -C {{ openwrt_imgbuilder_dir }}/{{ openwrt_tarball_basename }} image + {% if openwrt_profile is defined %}PROFILE="{{ openwrt_profile }}" {% endif %} + FILES="{{ openwrt_imgbuilder_files }}" + PACKAGES="{{ openwrt_packages }}" + {% if openwrt_extra_name is defined %} EXTRA_IMAGE_NAME="{{ openwrt_extra_name }}" {% endif %} + + - name: Copy newly built OpenWrt image + with_items: "{{ openwrt_output_image_suffixes }}" + copy: + src: "{{ openwrt_imgbuilder_dir }}/{{ openwrt_tarball_basename }}/bin/targets/{{ openwrt_arch }}/{{ openwrt_target }}/{{ openwrt_output_image_name_base }}-{{ item }}" + dest: "{{ openwrt_output_dir }}" + + always: + - name: Delete the temporary build directory + file: + path: "{{ openwrt_imgbuilder_dir }}" + state: absent diff --git a/roles/openwrt/image/tasks/prepare.yml b/roles/openwrt/image/tasks/prepare.yml new file mode 100644 index 00000000..3414371f --- /dev/null +++ b/roles/openwrt/image/tasks/prepare.yml @@ -0,0 +1,95 @@ +--- +- name: Create temporary build directory + tempfile: + state: directory + register: tmpdir + +- set_fact: + openwrt_imgbuilder_dir: "{{ tmpdir.path }}" + openwrt_imgbuilder_files: "{{ tmpdir.path }}/files" + +- name: Create the directories for mixins + file: + path: "{{ item }}" + state: directory + mode: '0755' + with_items: + - "{{ openwrt_download_dir }}/dl/{{ openwrt_arch }}" + - "{{ openwrt_imgbuilder_files }}/etc/config" + - "{{ openwrt_mixin | map('dirname') | map('regex_replace', '^', openwrt_imgbuilder_files) | unique | list }}" + + +- name: Copy mixins in place [1/2] + copy: + src: "{{ item.value.file }}" + dest: "{{ openwrt_imgbuilder_files }}/{{ item.key }}" + mode: "{{ item.value.mode | default('0644') }}" + with_dict: "{{ openwrt_mixin }}" + when: '"file" in item.value' + loop_control: + label: "{{ item.key }}" + +- name: Copy mixins in place [2/2] + copy: + content: "{{ item.value.content }}" + dest: "{{ openwrt_imgbuilder_files }}/{{ item.key }}" + mode: "{{ item.value.mode | default('0644') }}" + with_dict: "{{ openwrt_mixin }}" + when: '"content" in item.value' + loop_control: + label: "{{ item.key }}" + +- name: Generate /etc/fstab + mount: + fstab: "{{ openwrt_imgbuilder_files }}/etc/fstab" + state: present + src: "{{ item.src | default(omit) }}" + path: "{{ item.path | default(omit) }}" + fstype: "{{ item.fstype | default(omit) }}" + opts: "{{ item.opts | default(omit) }}" + boot: "{{ item.boot | default(omit) }}" + dump: "{{ item.dump | default(omit) }}" + passno: "{{ item.passno | default(omit) }}" + when: openwrt_mounts is defined + with_items: "{{ openwrt_mounts }}" + loop_control: + label: "{{ item.path }}" + + +- name: Create UCI configuration files + template: + src: uci.j2 + dest: "{{ openwrt_imgbuilder_files }}/etc/config/{{ item.key }}" + mode: 0644 + trim_blocks: yes +# force: no ## TODO: fail when overwriting a file + with_dict: "{{ openwrt_uci }}" + loop_control: + label: "{{ item.key }}" + +- name: Create /etc/passwd + template: + src: passwd.j2 + dest: "{{ openwrt_imgbuilder_files }}/etc/passwd" + mode: 0644 + trim_blocks: yes + when: openwrt_users is defined + +- name: Create /etc/group + template: + src: group.j2 + dest: "{{ openwrt_imgbuilder_files }}/etc/group" + mode: 0644 + trim_blocks: yes + when: openwrt_groups is defined or openwrt_users is defined + +- unarchive: + copy: False + src: "{{ openwrt_download_dir }}/{{ openwrt_tarball_name }}" + dest: "{{ openwrt_imgbuilder_dir }}" + +- name: Symlink the cache repository + file: + state: link + src: "{{ openwrt_download_dir }}/dl/{{ openwrt_arch }}" + path: "{{ openwrt_imgbuilder_dir }}/{{ openwrt_tarball_basename }}/dl" diff --git a/roles/openwrt/image/templates/group.j2 b/roles/openwrt/image/templates/group.j2 new file mode 100644 index 00000000..cb433b88 --- /dev/null +++ b/roles/openwrt/image/templates/group.j2 @@ -0,0 +1,21 @@ +{{ ansible_managed | comment }} +root:x:0: +daemon:x:1: +adm:x:4: +mail:x:8: +audio:x:29: +www-data:x:33: +ftp:x:55: +users:x:100: +network:x:101: +{% for name, opt in openwrt_users.items() %} +{% if 'group_id' not in opt %} +{{ name }}:x:{{ opt.id | default(loop.index + 110) }}: +{% endif %} +{% endfor %} +{% if openwrt_groups is defined %} +{% for name, opt in openwrt_groups.items() %} +{{ name }}:x:{{ opt.id | default(loop.index + 200) }}: +{% endfor %} +{% endif %} +nogroup:x:65534: diff --git a/roles/openwrt/image/templates/passwd.j2 b/roles/openwrt/image/templates/passwd.j2 new file mode 100644 index 00000000..9beaeb61 --- /dev/null +++ b/roles/openwrt/image/templates/passwd.j2 @@ -0,0 +1,9 @@ +{{ ansible_managed | comment }} +root:x:0:0:root:/root:/bin/ash +daemon:*:1:1:daemon:/var:/bin/false +ftp:*:55:55:ftp:/home/ftp:/bin/false +network:*:101:101:network:/var:/bin/false +{% for name, opt in openwrt_users.items() %} +{{ name }}:*:{{ opt.id | default(loop.index + 110) }}:{{ opt.gid | default(loop.index + 110) }}:{{ name }}:{{ opt.home | default('/nonexistent') }}:{{ opt.shell | default('/bin/false') }} +{% endfor %} +nobody:*:65534:65534:nobody:/var:/bin/false diff --git a/roles/openwrt/image/templates/uci.j2 b/roles/openwrt/image/templates/uci.j2 new file mode 100644 index 00000000..3cc480b2 --- /dev/null +++ b/roles/openwrt/image/templates/uci.j2 @@ -0,0 +1,15 @@ +{{ ansible_managed | comment }} + +{% for section in item.value %} +config {{ section.name }} +{% for option, value in section.options.items() %} +{% if value is iterable and value is not string %} +{% for v in value %} + list {{ option }} '{{ v }}' +{% endfor %} +{% else %} + option {{ option }} '{{ value }}' +{% endif %} +{% endfor %} + +{% endfor %} -- cgit v1.2.3