diff --git a/README b/README index 2c60c4f..e13b926 100644 --- a/README +++ b/README @@ -41,9 +41,8 @@ Installbox - LAN interface not configured/managed • Customize installbox.yml: - - set if_lan (mandatory) - - modify deb_mirror - - enable installbox2kiosk task + - set if_lan if necessary + - enable/disable installbox2kiosk task • Run ansible: ssh-copy-id ansible@1.2.3.4 diff --git a/installbox.yml b/installbox.yml index 850db30..a7418a0 100644 --- a/installbox.yml +++ b/installbox.yml @@ -1,28 +1,33 @@ --- -# This playbook deploys the installbox on a minimal installation. +## This playbook deploys the installbox. Add 'hostname=XXX' and +## 'domain=YYY' to the installer boot parameters to set hostname and +## domain. - name: apply configuration to the installbox hosts: all remote_user: ansible become: yes + vars: ## This interface provides the default route: if_wan: "{{ ansible_default_ipv4.interface }}" + ## Use the first remaining interface for the LAN: if_lan: "{{ ansible_interfaces | difference([if_wan, 'lo']) | first }}" - ## Add 'hostname=XXX' to the installer boot parameters if necessary: - hostname: "{{ ansible_hostname }}" + + ## LAN IP address range: ipaddr_lan: 192.168.0.10 dhcp_range: 192.168.0.50,192.168.0.150,2h dhcp_list: "{{ lookup('sequence', 'start=50 end=150 format=192.168.0.%d', wantlist=True) }}" - tftp_root: "/var/lib/tftpboot" - deb_mirror: "deb.debian.org" - di_dist: "buster" - di_version: "10" + + di_dist: "{{ ansible_distribution_release }}" + di_version: "{{ ansible_distribution_major_version }}" di_pkg: "debian-installer-{{ di_version }}-netboot-amd64" + ansible_user: ansible - repo_dir: "/home/{{ ansible_user }}/kiosk" - ansible_python_interpreter: "/usr/bin/python3" # needed for firewalld module + repo_dir: "/home/{{ ansible_user }}/debian-lan" + ansible_python_interpreter: "/usr/bin/python3" ## needed for firewalld module + pre_tasks: - name: validate if interfaces are available @@ -30,11 +35,11 @@ msg: "Interfaces {{ ansible_interfaces }} found. WAN: '{{ if_wan }}', LAN: '{{ if_lan }}'. Two NICs needed." when: (if_lan not in ansible_interfaces) or (if_wan not in ansible_interfaces) or (if_lan == if_wan) + roles: - up2date-debian - two-interface-firewalld - dhcp-dns-dnsmasq - tftp-netboot-installer - - preseed-installer - apt-cacher - - installbox2kiosk + - prepare4clients diff --git a/kerberox-client.yml b/kerberox-client.yml index 3170e0e..e54b505 100644 --- a/kerberox-client.yml +++ b/kerberox-client.yml @@ -16,7 +16,7 @@ - name: "kadmin_pwd" prompt: "Provide kadmin password to fetch kerberos keytab.\nLeave empty if done already" private: yes - + roles: - up2date-debian - lan-client diff --git a/kerberox.yml b/kerberox.yml index 1c34282..764359f 100644 --- a/kerberox.yml +++ b/kerberox.yml @@ -1,46 +1,52 @@ --- -# This playbook deploys the kerberox server. +## This playbook deploys the kerberox server. Add 'hostname=XXX' and +## 'domain=YYY' to the installer boot parameters to set hostname and domain. -- name: apply configuration to the installbox +- name: apply configuration to the kerberox server hosts: all remote_user: ansible become: yes + vars: ## This interface provides the default route: if_wan: "{{ ansible_default_ipv4.interface }}" + ## Use the first remaining interface for the LAN: if_lan: "{{ ansible_interfaces | difference([if_wan, 'lo']) | first }}" - ## Add 'hostname=XXX' to the installer boot parameters if necessary: - hostname: "{{ ansible_hostname }}" + + ## LAN IP address range: ipaddr_lan: 192.168.0.10 dhcp_range: 192.168.0.50,192.168.0.150,2h dhcp_list: "{{ lookup('sequence', 'start=50 end=150 format=192.168.0.%d', wantlist=True) }}" - tftp_root: "/var/lib/tftpboot" - deb_mirror: "deb.debian.org" + di_dist: "{{ ansible_distribution_release }}" - di_version: "{{ ansible_distribution_version }}" + di_version: "{{ ansible_distribution_major_version }}" di_pkg: "debian-installer-{{ di_version }}-netboot-amd64" + ansible_user: ansible repo_dir: "/home/{{ ansible_user }}/debian-lan" ansible_python_interpreter: "/usr/bin/python3" ## needed for firewalld module + vars_prompt: - name: "foo_pwd" prompt: "Provide a non-empty password for the test user 'foo'.\nLeave empty to continue without test user" private: yes + pre_tasks: - name: validate if interfaces are available fail: msg: "Interfaces {{ ansible_interfaces }} found. WAN: '{{ if_wan }}', LAN: '{{ if_lan }}'. Two NICs needed." when: (if_lan not in ansible_interfaces) or (if_wan not in ansible_interfaces) or (if_lan == if_wan) + roles: - up2date-debian - two-interface-firewalld - dhcp-dns-dnsmasq - tftp-netboot-installer - - preseed-installer - apt-cacher - krb5-kdc-ldap - nfs-server + - prepare4clients diff --git a/roles/apt-cacher/tasks/main.yml b/roles/apt-cacher/tasks/main.yml index c54a3a9..bb9cc51 100644 --- a/roles/apt-cacher/tasks/main.yml +++ b/roles/apt-cacher/tasks/main.yml @@ -9,5 +9,18 @@ dest: /etc/apt/apt.conf backup: yes notify: "start apt-cacher-ng" + when: not run_in_installer|default(false)|bool ## do not enable apt-cacher during installation + + +- name: check if preseeded installer is available + stat: path={{ tftp_root }}/d-i/{{ di_dist }}/preseed.cfg + register: preseedcfg + +- name: enable apt-cacher-ng for install-clients + replace: + dest: "{{ tftp_root }}/d-i/{{ di_dist }}/preseed.cfg" + regexp: '^(d-i mirror/http/proxy string.*)$' + replace: 'd-i mirror/http/proxy string http://{{ ansible_hostname }}:3142/' + when: preseedcfg.stat.exists - meta: flush_handlers diff --git a/roles/installbox2kiosk/tasks/main.yml b/roles/installbox2kiosk/tasks/main.yml deleted file mode 100644 index 6fe4f00..0000000 --- a/roles/installbox2kiosk/tasks/main.yml +++ /dev/null @@ -1,72 +0,0 @@ -- name: generate ssh key - command: "su -l {{ ansible_user }} -c \"ssh-keygen -t rsa -f /home/{{ ansible_user }}/.ssh/id_rsa -P ''\"" - args: - creates: "/home/{{ ansible_user }}/.ssh/id_rsa" - warn: False - -- name: slurp public key - slurp: - src: "/home/{{ ansible_user }}/.ssh/id_rsa.pub" - register: sshpubkey - -# The following seems to be necessary to get rid of a newline: -- set_fact: - sshpubkey: "{{ sshpubkey['content'] | b64decode | replace('\n', '') }}" - -- name: set debian mirror in preseed file - when: deb_mirror != "deb.debian.org" - replace: - dest: "{{ tftp_root }}/d-i/{{ di_dist }}/preseed.cfg" - regexp: '^(d-i mirror/http/hostname string deb.debian.org)$' - replace: '#\1\nd-i mirror/http/hostname string {{ deb_mirror }}' - -- name: enable backports in preseed file - replace: - dest: "{{ tftp_root }}/d-i/{{ di_dist }}/preseed.cfg" - regexp: '^#(apt-setup-udeb.*)$' - replace: '\1' - -- name: preseed client - add firmware-linux, ansible and git - replace: - dest: "{{ tftp_root }}/d-i/{{ di_dist }}/preseed.cfg" - regexp: '^(d-i pkgsel/include string firmware-linux)$' - replace: '#\1\nd-i pkgsel/include string firmware-linux ansible git' - -- name: insert start of managed block - replace: - dest: "{{ tftp_root }}/d-i/{{ di_dist }}/preseed.cfg" - regexp: '^(### This command is run just before the install finishes:)' - replace: '#\1\n# BEGIN ANSIBLE MANAGED BLOCK preseed/late_command' - -- name: insert end of managed block - replace: - dest: "{{ tftp_root }}/d-i/{{ di_dist }}/preseed.cfg" - regexp: '^(## When installing.*)' - replace: '# END ANSIBLE MANAGED BLOCK preseed/late_command\n#\1' - -- name: insert block - blockinfile: - dest: "{{ tftp_root }}/d-i/{{ di_dist }}/preseed.cfg" - insertafter: "^### This command is run just before the install finishes:" - block: | - d-i preseed/late_command string \ - mkdir -p /target/home/ansible/.ssh && \ - echo "{{ sshpubkey }}" >> /target/home/ansible/.ssh/authorized_keys ; \ - in-target chown -R ansible:ansible /home/ansible/.ssh/ ; \ - in-target chmod -R og= /home/ansible/.ssh/ ; \ - in-target ansible-pull --verbose --purge --extra-vars="run_in_installer=true" \ - -i localhost, --url=git://{{ hostname }}/.git $playbook - marker: "# {mark} ANSIBLE MANAGED BLOCK preseed/late_command" - -- name: provide git repo if not available already - git: - repo: 'https://salsa.debian.org/andi/debian-lan-ansible.git' - dest: "{{ repo_dir }}" - update: no - become_user: "ansible" - -- name: start git-repo - template: - src: git-repo.j2 - dest: "/etc/systemd/system/git-repo.service" - notify: start git-repo diff --git a/roles/krb5-kdc-ldap/tasks/main.yml b/roles/krb5-kdc-ldap/tasks/main.yml index fc27565..59d289f 100644 --- a/roles/krb5-kdc-ldap/tasks/main.yml +++ b/roles/krb5-kdc-ldap/tasks/main.yml @@ -4,7 +4,7 @@ - fail: msg="The machine's domain must not be empty." when: ansible_domain | length == 0 -- name: check if slapd is already there +- name: check if krb5kdc is already there stat: path=/usr/sbin/krb5kdc register: krb5kdc diff --git a/roles/ldap/tasks/main.yml b/roles/ldap/tasks/main.yml index c8564d4..131e8c9 100644 --- a/roles/ldap/tasks/main.yml +++ b/roles/ldap/tasks/main.yml @@ -53,7 +53,7 @@ src: slapd-config.ldif dest: /etc/ldap/slapd.d/slapd-config.ldif when: not slapd.stat.exists - + - name: activate ppolicy schema command: ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/ppolicy.ldif when: not slapd.stat.exists @@ -128,6 +128,6 @@ ## Use firewall-offline-cmd when run during installation: -- name: allow ldap service in firewalld +- name: allow ldap service in firewalld command: "firewall-offline-cmd --zone=internal --add-service=ldap" when: run_in_installer|default(false)|bool diff --git a/roles/installbox2kiosk/handlers/main.yml b/roles/prepare4clients/handlers/main.yml similarity index 100% rename from roles/installbox2kiosk/handlers/main.yml rename to roles/prepare4clients/handlers/main.yml diff --git a/roles/prepare4clients/tasks/main.yml b/roles/prepare4clients/tasks/main.yml new file mode 100644 index 0000000..4ae6d3f --- /dev/null +++ b/roles/prepare4clients/tasks/main.yml @@ -0,0 +1,146 @@ +- name: generate ssh key + command: "su -l {{ ansible_user }} -c \"ssh-keygen -t rsa -f /home/{{ ansible_user }}/.ssh/id_rsa -P ''\"" + args: + creates: "/home/{{ ansible_user }}/.ssh/id_rsa" + warn: False + +- name: slurp public key + slurp: + src: "/home/{{ ansible_user }}/.ssh/id_rsa.pub" + register: sshpubkey + +# The following seems to be necessary to get rid of a newline: +- set_fact: + sshpubkey: "{{ sshpubkey['content'] | b64decode | replace('\n', '') }}" + +- name: enable backports in preseed file + replace: + dest: "{{ tftp_root }}/d-i/{{ di_dist }}/preseed.cfg" + regexp: '^#(apt-setup-udeb.*)$' + replace: '\1' + +- name: preseed client - add firmware-linux, ansible and git + replace: + dest: "{{ tftp_root }}/d-i/{{ di_dist }}/preseed.cfg" + regexp: '^(d-i pkgsel/include string firmware-linux)$' + replace: '#\1\nd-i pkgsel/include string firmware-linux ansible git' + +- name: insert start of managed block + replace: + dest: "{{ tftp_root }}/d-i/{{ di_dist }}/preseed.cfg" + regexp: '^(### This command is run just before the install finishes:)' + replace: '#\1\n# BEGIN ANSIBLE MANAGED BLOCK preseed/late_command' + +- name: insert end of managed block + replace: + dest: "{{ tftp_root }}/d-i/{{ di_dist }}/preseed.cfg" + regexp: '^(## When installing.*)' + replace: '# END ANSIBLE MANAGED BLOCK preseed/late_command\n#\1' + +- name: insert block + blockinfile: + dest: "{{ tftp_root }}/d-i/{{ di_dist }}/preseed.cfg" + insertafter: "^### This command is run just before the install finishes:" + block: | + d-i preseed/late_command string \ + mkdir -p /target/home/ansible/.ssh && \ + echo "{{ sshpubkey }}" >> /target/home/ansible/.ssh/authorized_keys ; \ + in-target chown -R ansible:ansible /home/ansible/.ssh/ ; \ + in-target chmod -R og= /home/ansible/.ssh/ ; \ + in-target ansible-pull --verbose --purge --extra-vars="run_in_installer=true" \ + -i localhost, --url=git://{{ ansible_hostname }}/.git $playbook + marker: "# {mark} ANSIBLE MANAGED BLOCK preseed/late_command" + +- name: add kiosk auto pxe boot entry to di-netboot-assistant + blockinfile: + dest: /etc/di-netboot-assistant/pxelinux.HEAD + insertbefore: EOF + block: | + TIMEOUT 100 + # Use a temporary package cache during installation, install etckeeper. + LABEL tmp pkg cache + MENU LABEL Debian stable (amd64) + temporary package cache + kernel ::/d-i/n-pkg/images/{{ di_version }}/amd64/text/debian-installer/amd64/linux + append initrd=::/d-i/n-pkg/images/{{ di_version }}/amd64/text/debian-installer/amd64/initrd.gz mirror/http/proxy?=http://{{ ansible_hostname }}:3142/ pkgsel/include=etckeeper preseed/late_command="rm -fv /target/etc/apt/apt.conf" --- + + LABEL autoinstall + MENU LABEL Debian {{ di_version }} (amd64) + preseed + kiosk.yml + kernel ::/d-i/n-pkg/images/{{ di_version }}/amd64/text/debian-installer/amd64/linux + append initrd=::/d-i/n-pkg/images/{{ di_version }}/amd64/text/debian-installer/amd64/initrd.gz auto=true priority=critical url=tftp://{{ ansible_hostname }} playbook=kiosk.yml --- + + #LABEL daily + #MENU LABEL Debian daily (amd64) + preseed + kiosk.yml + #kernel ::/d-i/n-a/daily/amd64/linux + #append initrd=::/d-i/n-a/daily/amd64/initrd.gz auto=true priority=critical url=tftp://{{ ansible_hostname }} playbook=kiosk.yml --- + marker: "# {mark} ANSIBLE MANAGED BLOCK kiosk" + notify: "rebuild di-netboot-assistant menu" + +- name: add kiosk auto efi boot entry to di-netboot-assistant + blockinfile: + dest: /etc/di-netboot-assistant/grub.cfg.HEAD + insertbefore: EOF + block: | + # Use a temporary package cache during installation, install etckeeper. + menuentry 'Debian stable (amd64) + temporary package cache' { + linux /d-i/n-pkg/images/{{ di_version }}/amd64/text/debian-installer/amd64/linux mirror/http/proxy?=http://{{ ansible_hostname }}:3142/ pkgsel/include=etckeeper preseed/late_command="rm -fv /target/etc/apt/apt.conf" --- + initrd /d-i/n-pkg/images/{{ di_version }}/amd64/text/debian-installer/amd64/initrd.gz + } + + menuentry 'Debian {{ di_version }} (amd64) + preseed + kiosk.yml' { + linux /d-i/n-pkg/images/{{ di_version }}/amd64/text/debian-installer/amd64/linux auto=true priority=critical url=tftp://{{ ansible_hostname }} playbook=kiosk.yml --- + initrd /d-i/n-pkg/images/{{ di_version }}/amd64/text/debian-installer/amd64/initrd.gz + } + + #menuentry 'Debian daily (amd64) + preseed + kiosk.yml' { + # linux /d-i/n-a/daily/amd64/linux auto=true priority=critical url=tftp://{{ ansible_hostname }} playbook=kiosk.yml --- + # initrd /d-i/n-a/daily/amd64/initrd.gz + #} + marker: "# {mark} ANSIBLE MANAGED BLOCK kiosk" + notify: "rebuild di-netboot-assistant menu" + +######## kerberox-client ####### + +- name: check if we opereate on kerberox + stat: path=/usr/sbin/krb5kdc + register: krb5kdc + +- name: add kerberox-client auto pxe boot entry to di-netboot-assistant + blockinfile: + dest: /etc/di-netboot-assistant/pxelinux.HEAD + insertbefore: EOF + block: | + LABEL autoinstall + MENU LABEL Debian {{ di_version }} (amd64) + preseed + kerberox-client.yml + kernel ::/d-i/n-pkg/images/{{ di_version }}/amd64/text/debian-installer/amd64/linux + append initrd=::/d-i/n-pkg/images/{{ di_version }}/amd64/text/debian-installer/amd64/initrd.gz auto=true priority=critical url=tftp://{{ ansible_hostname }} playbook=kerberox-client.yml --- + marker: "# {mark} ANSIBLE MANAGED BLOCK kerberox-client" + notify: "rebuild di-netboot-assistant menu" + when: krb5kdc.stat.exists + +- name: add kerberox-client auto efi boot entry to di-netboot-assistant + blockinfile: + dest: /etc/di-netboot-assistant/grub.cfg.HEAD + insertbefore: EOF + block: | + menuentry 'Debian {{ di_version }} (amd64) + preseed + kerberox-client.yml' { + linux /d-i/n-pkg/images/{{ di_version }}/amd64/text/debian-installer/amd64/linux auto=true priority=critical url=tftp://{{ ansible_hostname }} playbook=kerberox-client.yml --- + initrd /d-i/n-pkg/images/{{ di_version }}/amd64/text/debian-installer/amd64/initrd.gz + } + marker: "# {mark} ANSIBLE MANAGED BLOCK kerberox-client" + notify: "rebuild di-netboot-assistant menu" + when: krb5kdc.stat.exists + +###################### + +- name: provide git repo if not available already + git: + repo: 'https://salsa.debian.org/andi/debian-lan-ansible.git' + dest: "{{ repo_dir }}" + update: no + become_user: "ansible" + +- name: start git-repo + template: + src: git-repo.j2 + dest: "/etc/systemd/system/git-repo.service" + notify: start git-repo diff --git a/roles/installbox2kiosk/templates/git-repo.j2 b/roles/prepare4clients/templates/git-repo.j2 similarity index 100% rename from roles/installbox2kiosk/templates/git-repo.j2 rename to roles/prepare4clients/templates/git-repo.j2 diff --git a/roles/preseed-installer/tasks/main.yml b/roles/preseed-installer/tasks/main.yml deleted file mode 100644 index 8435208..0000000 --- a/roles/preseed-installer/tasks/main.yml +++ /dev/null @@ -1,55 +0,0 @@ -- name: make preseed directory available - file: - path: "{{ tftp_root }}/d-i/{{ di_dist }}" - state: directory - -- name: provide preseed file - copy: - src: /usr/share/doc/di-netboot-assistant/examples/preseed.cfg - dest: "{{ tftp_root }}/d-i/{{ di_dist }}" - force: no - -- name: enable apt-cacher-ng for install-clients - replace: - dest: "{{ tftp_root }}/d-i/{{ di_dist }}/preseed.cfg" - regexp: '^(d-i mirror/http/proxy string.*)$' - replace: 'd-i mirror/http/proxy string http://{{ hostname }}:3142/' - -- name: make the hostname resolvable from the LAN - replace: - path: /etc/hosts - regexp: '^(127\.0\.1\.1.*)$' - replace: '#\1\n{{ ipaddr_lan }} {{ hostname }}' - -- name: add auto pxe boot entry to di-netboot-assistant - blockinfile: - dest: /etc/di-netboot-assistant/pxelinux.HEAD - insertbefore: EOF - block: | - TIMEOUT 100 - LABEL autoinstall - MENU LABEL Debian {{ di_version }} (amd64) + preseed + kiosk.yml - kernel ::/d-i/n-pkg/images/{{ di_version }}/amd64/text/debian-installer/amd64/linux - append initrd=::/d-i/n-pkg/images/{{ di_version }}/amd64/text/debian-installer/amd64/initrd.gz auto=true priority=critical url=tftp://{{ hostname }} playbook=kiosk.yml --- - - #LABEL daily - #MENU LABEL Debian daily (amd64) + preseed + kiosk.yml - #kernel ::/d-i/n-a/daily/amd64/linux - #append initrd=::/d-i/n-a/daily/amd64/initrd.gz auto=true priority=critical url=tftp://{{ hostname }} playbook=kiosk.yml --- - notify: "rebuild di-netboot-assistant menu" - -- name: add auto efi boot entry to di-netboot-assistant - blockinfile: - dest: /etc/di-netboot-assistant/grub.cfg.HEAD - insertbefore: EOF - block: | - menuentry 'Debian {{ di_version }} (amd64) + preseed + kiosk.yml' { - linux /d-i/n-pkg/images/{{ di_version }}/amd64/text/debian-installer/amd64/linux auto=true priority=critical url=tftp://{{ hostname }} playbook=kiosk.yml --- - initrd /d-i/n-pkg/images/{{ di_version }}/amd64/text/debian-installer/amd64/initrd.gz - } - - #menuentry 'Debian daily (amd64) + preseed + kiosk.yml' { - # linux /d-i/n-a/daily/amd64/linux auto=true priority=critical url=tftp://{{ hostname }} playbook=kiosk.yml --- - # initrd /d-i/n-a/daily/amd64/initrd.gz - #} - notify: "rebuild di-netboot-assistant menu" diff --git a/roles/tftp-netboot-installer/defaults/main.yml b/roles/tftp-netboot-installer/defaults/main.yml new file mode 100644 index 0000000..2b791ea --- /dev/null +++ b/roles/tftp-netboot-installer/defaults/main.yml @@ -0,0 +1 @@ +tftp_root: "/var/lib/tftpboot" diff --git a/roles/tftp-netboot-installer/tasks/main.yml b/roles/tftp-netboot-installer/tasks/main.yml index 31df608..a70a711 100644 --- a/roles/tftp-netboot-installer/tasks/main.yml +++ b/roles/tftp-netboot-installer/tasks/main.yml @@ -1,3 +1,8 @@ +- name: make preseed directory available + file: + path: "{{ tftp_root }}/d-i/{{ di_dist }}" + state: directory + - name: install di-netboot-assistant and installer package apt: name: @@ -7,6 +12,12 @@ - bind mount images - rebuild di-netboot-assistant menu +- name: provide preseed file + copy: + src: /usr/share/doc/di-netboot-assistant/examples/preseed.cfg + dest: "{{ tftp_root }}/d-i/{{ di_dist }}" + force: no + - name: configure dnsmasq template: src: dnsmasq-tftp-netboot-installer.j2 @@ -14,3 +25,9 @@ notify: - restart dnsmasq - rebuild di-netboot-assistant menu + +- name: make the hostname resolvable from the LAN + replace: + path: /etc/hosts + regexp: '^(127\.0\.1\.1.*)$' + replace: '#\1\n{{ ipaddr_lan }} {{ ansible_hostname }}.{{ ansible_domain }} {{ ansible_hostname }}' diff --git a/roles/two-interface-firewalld/tasks/main.yml b/roles/two-interface-firewalld/tasks/main.yml index dd5a05e..d61dc39 100644 --- a/roles/two-interface-firewalld/tasks/main.yml +++ b/roles/two-interface-firewalld/tasks/main.yml @@ -24,7 +24,7 @@ - name: enable masquerading firewalld: zone: public - masquerade: yes + masquerade: 'yes' permanent: yes state: enabled when: not run_in_installer|default(false)|bool