Merge PR#17: add accesspoints playbook
authornicoo <nicoo@realraum.at>
Mon, 26 Nov 2018 21:36:54 +0000 (22:36 +0100)
committernicoo <nicoo@realraum.at>
Mon, 26 Nov 2018 21:36:54 +0000 (22:36 +0100)
20 files changed:
ansible.cfg [new file with mode: 0644]
ansible/group_vars/accesspoints/main.yml [new file with mode: 0644]
ansible/group_vars/accesspoints/vault.yml [new file with mode: 0644]
ansible/group_vars/all/main.yml
ansible/group_vars/openwrt/main.yml
ansible/host_playbooks/accesspoints.yml [new file with mode: 0644]
ansible/host_vars/torwaechter/main.yml
ansible/hosts.ini
ansible/roles/localconfig/templates/ssh/10r3.conf.j2
ansible/roles/openwrt-image/README.md
ansible/roles/openwrt-image/defaults/main.yml
ansible/roles/openwrt-image/group.j2 [deleted file]
ansible/roles/openwrt-image/openwrt-keyring.gpg
ansible/roles/openwrt-image/passwd.j2 [deleted file]
ansible/roles/openwrt-image/tasks/main.yml
ansible/roles/openwrt-image/tasks/prepare.yml
ansible/roles/openwrt-image/templates/group.j2 [new file with mode: 0644]
ansible/roles/openwrt-image/templates/passwd.j2 [new file with mode: 0644]
ansible/roles/openwrt-image/templates/uci.j2 [new file with mode: 0644]
ansible/roles/openwrt-image/uci.j2 [deleted file]

diff --git a/ansible.cfg b/ansible.cfg
new file mode 100644 (file)
index 0000000..f062f5f
--- /dev/null
@@ -0,0 +1,3 @@
+[defaults]
+# Dirty hack to make git-diff & friends work
+vault_password_file = ./ansible/gpg/get-vault-pass.sh
diff --git a/ansible/group_vars/accesspoints/main.yml b/ansible/group_vars/accesspoints/main.yml
new file mode 100644 (file)
index 0000000..1df3d41
--- /dev/null
@@ -0,0 +1,207 @@
+---
+accesspoint_wifi_channels:
+  2.4g:
+    ap0: 3
+    ap1: 8
+    ap2: 13
+  5g:
+    ap0: 36
+    ap1: 48
+    ap2: 40
+
+accesspoint_zones:
+  iot:
+    ssid: "TEST realstuff"
+    encryption: "psk2"
+    key: "{{ vault_accesspoint_zones.iot.key }}"
+  guests:
+    ssid: "TEST realraum"
+    encryption: "psk2"
+    key: "{{ vault_accesspoint_zones.guests.key }}"
+  # members:
+  #   ssid: "TEST r3members"
+  #   encryption: "psk2"
+  #   key: "{{ vault_accesspoint_zones.members.key }}"
+
+
+
+accesspoint_wired_interface: eth0
+accesspoint_wireless_device_paths:
+  2.4g: "platform/qca956x_wmac"
+  5g: "pci0000:00/0000:00:00.0"
+
+accesspoint_network_base:
+  - name: globals 'globals'
+    options:
+      ula_prefix: "fc{{ '%02x:%04x:%04x' | format((255 | random(seed=inventory_hostname + '0')), (65535 | random(seed=inventory_hostname + '1')), (65535 | random(seed=inventory_hostname + '2'))) }}::/48"
+
+  - name: interface 'loopback'
+    options:
+      ifname: lo
+      proto: static
+      ipaddr: 127.0.0.1
+      netmask: 255.0.0.0
+
+  - name: interface 'raw'
+    options:
+      ifname: "{{ accesspoint_wired_interface }}"
+      proto: none
+      accept_ra: 0
+
+  - name: interface 'mgmt'
+    options:
+      type: bridge
+      ifname: "{{ accesspoint_wired_interface }}.{{ net.mgmt.vlan }}"
+      accept_ra: 0
+      proto: static
+      ipaddr: "{{ net.mgmt.prefix | ipaddr(net.mgmt.offsets.accesspoints + groups.accesspoints.index(inventory_hostname)) | ipaddr('address') }}"
+      netmask: "{{ net.mgmt.prefix | ipaddr('netmask') }}"
+      gateway: "{{ net.mgmt.gw }}"
+      dns: "{{ net.mgmt.dns | join(' ') }}"
+      dns_search: realraum.at
+
+accesspoint_network_zones: "{{ accesspoint_network_zones_yaml | from_yaml }}"
+accesspoint_network_zones_yaml: |
+  {% for item in accesspoint_zones.keys() %}
+  - name: interface "{{ item }}"
+    options:
+      type: bridge
+      ifname: "{{ accesspoint_wired_interface }}.{{ net[item].vlan }}"
+      accept_ra: 0
+      proto: none
+  {% endfor %}
+
+
+accesspoint_wireless_devices:
+  - name: wifi-device 'radio5g'
+    options:
+      type: 'mac80211'
+      channel: "{{ accesspoint_wifi_channels['5g'][inventory_hostname] }}"
+      hwmode: '11a'
+      country: AT
+      path: "{{ accesspoint_wireless_device_paths['5g'] }}"
+      htmode: 'VHT80'
+
+  - name: wifi-device 'radio2g4'
+    options:
+      type: 'mac80211'
+      channel: "{{ accesspoint_wifi_channels['2.4g'][inventory_hostname] }}"
+      hwmode: '11g'
+      country: AT
+      path: "{{ accesspoint_wireless_device_paths['2.4g'] }}"
+      htmode: 'HT20'
+
+
+## TODO: set up 802.11r see:
+##        * https://www.reddit.com/r/openwrt/comments/515oea/finally_got_80211r_roaming_working/
+##        * https://gist.github.com/lg/998d3e908d547bd9972a6bb604df377b
+accesspoint_wireless_ifaces: "{{ accesspoint_wireless_ifaces_yaml | from_yaml }}"
+accesspoint_wireless_types:
+  - { name: only, ssid: 2.4, freq: 2g4 }
+  - { name: only, ssid: 5, freq: 5g }
+  - { name: '', ssid: '', freq: 2g4 }
+  - { name: '', ssid: '', freq: 5g }
+accesspoint_wireless_ifaces_yaml: |
+  {% for zone in accesspoint_zones.keys() %}
+  {%   for item in accesspoint_wireless_types %}
+  - name: wifi-iface '{{ zone }}{{ item.freq }}{{ item.name }}'
+    options:
+      device: 'radio{{ item.freq }}'
+      network: '{{ zone }}'
+      mode: 'ap'
+      disassoc_low_ack: '1'
+      rsn_preauth: '1'
+      ssid: '{{ accesspoint_zones[zone].ssid }}{{ item.ssid }}'
+      encryption: '{{ accesspoint_zones[zone].encryption }}'
+      key: '{{ accesspoint_zones[zone].key }}'
+  {%   endfor %}
+  {% endfor %}
+
+
+
+openwrt_variant: openwrt
+openwrt_release: 18.06.1
+openwrt_arch: ar71xx
+openwrt_target: generic
+openwrt_profile: ubnt-unifiac-lite
+openwrt_output_image_suffixes:
+  - "generic-{{ openwrt_profile }}-squashfs-sysupgrade.bin"
+
+openwrt_mixin:
+  /etc/sysctl.conf:
+    content: |
+      # Defaults are configured in /etc/sysctl.d/* and can be customized in this file
+      #
+      # disable IP forwarding, we don't need it since we are
+      # only an AP that bridges VLANs to Wifi SSIDs
+      net.ipv4.conf.default.forwarding=0
+      net.ipv4.conf.all.forwarding=0
+      net.ipv4.ip_forward=0
+      net.ipv6.conf.default.forwarding=0
+      net.ipv6.conf.all.forwarding=0
+
+  /etc/dropbear/authorized_keys:
+    content: |-
+      {% for key in noc_ssh_keys %}
+      {{ key }}
+      {% endfor %}
+
+  /root/.config/htop/htoprc:
+    content: |
+      # 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=0
+      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=AllCPUs Memory Swap
+      left_meter_modes=1 1 1
+      right_meters=Tasks LoadAverage Uptime
+      right_meter_modes=2 2 2
+
+
+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'
+
+  network: "{{ accesspoint_network_base + accesspoint_network_zones }}"
+  wireless: "{{ accesspoint_wireless_devices + accesspoint_wireless_ifaces }}"
diff --git a/ansible/group_vars/accesspoints/vault.yml b/ansible/group_vars/accesspoints/vault.yml
new file mode 100644 (file)
index 0000000..310334d
--- /dev/null
@@ -0,0 +1,14 @@
+$ANSIBLE_VAULT;1.1;AES256
+64316132376664633237633361636561366134623562623338396235356134383434383766343337
+6665383561306465383139633065373037626336336237370a616530393563376637316434653632
+34373735393365396439633630653838353630636130663233393031383630326434336162626166
+3764383533363766380a383764393436316262653131363933303838396664616635623338653632
+64636434353631653939383235303863646336353037396632303561303564306539626461306634
+64393964323035336434346664346139313164333764643038323262646139376366333830636366
+63656266376430663462626133376535373337656461373832653736646136626135366264343736
+32663338636264356634393562663036356239353963356233333066366564383631666466376430
+30353038626163353564396137366634336362393562386539373732343766383164376131643962
+30653063376333336336313635663334366631633239643063396537386535653238613763663563
+31663963313232643161313431373334666638646139313035666334626334363661613261383630
+35643834626431346234306264643265623934303033316339663135633731356133623631346335
+66396636663134626339326466396434343436346533323161316639366265326132
index 1301aef..cd8f05d 100644 (file)
@@ -1,7 +1,7 @@
 ---
 # Build-related directories
-global_cache_dir: "{{ inventory_dir }}/.cache/"
-global_artifacts_dir: "{{ inventory_dir }}/files/"
+global_cache_dir: "{{ inventory_dir }}/.cache"
+global_artifacts_dir: "{{ inventory_dir }}/files"
 
 # Default credentials
 ## Root password; by default, undefined
index b93d046..2c29b78 100644 (file)
@@ -5,10 +5,10 @@ openwrt_packages_remove:
   - dnsmasq
   - firewall
   - odhcpd
+  - odhcpd-ipv6only
 openwrt_packages_add:
   - haveged
   - htop
-  - hwclock
   - ip
   - less
   - nano
diff --git a/ansible/host_playbooks/accesspoints.yml b/ansible/host_playbooks/accesspoints.yml
new file mode 100644 (file)
index 0000000..dd8b95a
--- /dev/null
@@ -0,0 +1,6 @@
+---
+- hosts: accesspoints
+  connection: local
+  roles:
+    - role: openwrt-image
+      delegate_to: localhost
index 926b903..2a2316f 100644 (file)
@@ -7,6 +7,7 @@ openwrt_output_image_suffixes:
 
 openwrt_packages_extra:
   - "-dropbear"
+  - hwclock
   - flashrom
   - git
   - kmod-usb-acm
index 460ca5f..26bb727 100644 (file)
@@ -19,6 +19,9 @@ gnocchi[0:1]
 metrics localconfig_ssh_config_user=root
 testvm localconfig_ssh_config_user=root
 
+[net-zone-mgmt:children]
+accesspoints
+
 [net-zone-mgmt:vars]
 host_domain=mgmt.realraum.at
 
@@ -62,10 +65,15 @@ virtualservers
 [desktops]
 wuerfel
 
+[accesspoints]
+ap[0:2]
 
 [openwrt]
 torwaechter
 
+[openwrt:children]
+accesspoints
+
 [openwrt:vars]
 localconfig_ssh_config_user=root
 
index 9389b94..73ed53c 100644 (file)
@@ -24,18 +24,6 @@ Host {{ hostvars[host].ansible_host }} r3-{{ host }} r3g-{{ host }} r3e-{{ host
 Host gw.realraum.at r3-gw
     Hostname gw.realraum.at
 
-Host ap0.mgmt.realraum.at r3g-ap0
-    Hostname ap0.mgmt.realraum.at
-    User root
-
-Host ap1.mgmt.realraum.at r3g-ap1
-    Hostname ap1.mgmt.realraum.at
-    User root
-
-Host ap2.mgmt.realraum.at r3g-ap2
-    Hostname ap2.mgmt.realraum.at
-    User root
-
 Host licht.realraum.at r3-licht r3g-licht r3e-licht
     Hostname licht.realraum.at
     User realraum
index d56affe..95d9d10 100644 (file)
@@ -1,3 +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
index cb4427d..f00a2e8 100644 (file)
@@ -2,7 +2,7 @@
 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 }}{% if openwrt_target != 'generic' %}-{{ openwrt_target }}{% endif %}.Linux-x86_64"
+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
 
diff --git a/ansible/roles/openwrt-image/group.j2 b/ansible/roles/openwrt-image/group.j2
deleted file mode 100644 (file)
index cb433b8..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-{{ 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:
index f4cab00..e8a3e8b 100644 (file)
Binary files a/ansible/roles/openwrt-image/openwrt-keyring.gpg and b/ansible/roles/openwrt-image/openwrt-keyring.gpg differ
diff --git a/ansible/roles/openwrt-image/passwd.j2 b/ansible/roles/openwrt-image/passwd.j2
deleted file mode 100644 (file)
index 9beaeb6..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-{{ 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
index 5f9cc52..1781d9e 100644 (file)
@@ -1,5 +1,6 @@
 ---
 - include: fetch.yml
+  run_once: true
   when: openwrt_imgbuilder_tarball is not defined
 
 - block:
@@ -19,6 +20,7 @@
     - 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 %}
index f403cad..b6b67c5 100644 (file)
@@ -13,7 +13,7 @@
     state: directory
     mode: '0755'
   with_items:
-    - "{{ openwrt_download_dir }}/dl"
+    - "{{ openwrt_download_dir }}/dl/{{ openwrt_arch }}"
     - "{{ openwrt_imgbuilder_files }}/etc/config"
     - "{{ openwrt_mixin | map('dirname') | map('regex_replace', '^', openwrt_imgbuilder_files) | unique | list }}"
 
@@ -90,5 +90,5 @@
 - name: Symlink the cache repository
   file:
     state: link
-    src: "{{ openwrt_download_dir }}/dl"
+    src: "{{ openwrt_download_dir }}/dl/{{ openwrt_arch }}"
     path: "{{ openwrt_imgbuilder_dir }}/{{ openwrt_tarball_basename }}/dl"
diff --git a/ansible/roles/openwrt-image/templates/group.j2 b/ansible/roles/openwrt-image/templates/group.j2
new file mode 100644 (file)
index 0000000..cb433b8
--- /dev/null
@@ -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/ansible/roles/openwrt-image/templates/passwd.j2 b/ansible/roles/openwrt-image/templates/passwd.j2
new file mode 100644 (file)
index 0000000..9beaeb6
--- /dev/null
@@ -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/ansible/roles/openwrt-image/templates/uci.j2 b/ansible/roles/openwrt-image/templates/uci.j2
new file mode 100644 (file)
index 0000000..3cc480b
--- /dev/null
@@ -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 %}
diff --git a/ansible/roles/openwrt-image/uci.j2 b/ansible/roles/openwrt-image/uci.j2
deleted file mode 100644 (file)
index 3cc480b..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-{{ 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 %}