From 49a1dc59c274694c2daca214f5ffed4205f9a941 Mon Sep 17 00:00:00 2001 From: Donavan Fritz Date: Wed, 1 Jan 2025 17:02:38 -0600 Subject: [PATCH] inital commit of LXC base image creation --- README.md | 12 +- lxc/inventory-host-proxmox.yaml | 14 +++ lxc/playbook-base-lxc.yaml | 181 +++++++++++++++++++++++++++++++ lxc/templates/authorized_keys.j2 | 1 + lxc/templates/bash.bashrc.j2 | 51 +++++++++ lxc/templates/digrc.j2 | 1 + lxc/templates/environment.j2 | 4 + lxc/templates/locale.j2 | 1 + lxc/templates/motd.j2 | 6 + lxc/templates/sshd_banner.j2 | 6 + lxc/templates/sshd_config.j2 | 3 + lxc/templates/sysctl.j2 | 2 + 12 files changed, 280 insertions(+), 2 deletions(-) create mode 100644 lxc/inventory-host-proxmox.yaml create mode 100644 lxc/playbook-base-lxc.yaml create mode 100644 lxc/templates/authorized_keys.j2 create mode 100644 lxc/templates/bash.bashrc.j2 create mode 100644 lxc/templates/digrc.j2 create mode 100644 lxc/templates/environment.j2 create mode 100644 lxc/templates/locale.j2 create mode 100644 lxc/templates/motd.j2 create mode 100644 lxc/templates/sshd_banner.j2 create mode 100644 lxc/templates/sshd_config.j2 create mode 100644 lxc/templates/sysctl.j2 diff --git a/README.md b/README.md index 34f7ac4..c99906b 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,15 @@ The following playbook will set the iDRAC settings for all hosts in the inventor $ ansible-playbook --vault-password-file vault-password compute/playbook-machine-idrac.yaml -i compute/inventory-machine-idrac.yaml ``` +### Fritzlab LXC Base Image + +We manage the Fritzlab LXC base image via Ansible. +The following playbook will create the base image on the Proxmox host. + +```bash +$ ansible-playbook --vault-password-file vault-password lxc/playbook-base-lxc.yaml -i lxc/inventory-host-proxmox.yaml +``` + ### Secrets We use ansible-vault to encrypt secrets. @@ -53,5 +62,4 @@ dell_machines: 39336366666137623230393261633166313837303432653336636363393936323133636366313636 3738316235663337370a333031643466323962643034313433666236313831643861656461643833 35316235356566333761333635356337373632646365343364373563613034636334 -``` - +``` \ No newline at end of file diff --git a/lxc/inventory-host-proxmox.yaml b/lxc/inventory-host-proxmox.yaml new file mode 100644 index 0000000..750000f --- /dev/null +++ b/lxc/inventory-host-proxmox.yaml @@ -0,0 +1,14 @@ +all: + hosts: + host201: + ansible_user: root + ansible_password: !vault | + $ANSIBLE_VAULT;1.1;AES256 + 63366438616366643633383736323435656637386137376166613765663962623761333762663461 + 3966613863636636376636343533623936666334626336620a623433363830326262663238636532 + 34323731623766396163313063333266666266396539616533626135656661393064613530326633 + 3336643339616434650a313464653764666264346564363166656531306165613037623035333038 + 33336337303565663530626632666462313832316231306633333263396164306462 + ansible_host: host201.sjc001.fritzlab.net + ipv4_address: 172.25.6.201 + ipv6_address: 2602:817:3000:c206::201 diff --git a/lxc/playbook-base-lxc.yaml b/lxc/playbook-base-lxc.yaml new file mode 100644 index 0000000..91470c5 --- /dev/null +++ b/lxc/playbook-base-lxc.yaml @@ -0,0 +1,181 @@ +--- +- name: Create Fritzlab Base LXC Container + hosts: + - "host201" + become: true + vars: + debian_os: "debian" + debian_version: "bookworm" + lxc_name: "fritzlab-base" + lxc_image_artifact_name: "{{ lxc_name }}-{{ timestamp }}.tar.gz" + lxc_base_dir: "/var/lib/lxc" + lxc_template_dir: "/var/lib/vz/template/cache" + working_lxc_dir: "{{ lxc_base_dir }}/{{ lxc_name }}" + working_rootfs_dir: "{{ working_lxc_dir }}/rootfs" + working_chroot: "chroot {{ working_rootfs_dir }}" + lxc_unnecessary_units: + - nftables.service + - systemd-logind.service + - systemd-sysusers.service + - systemd-tmpfiles-setup-dev.service + - systemd-tmpfiles-setup.service + - postfix.service + - iperf3.service + - sys-kernel-config.mount + - sys-kernel-debug.mount + debian_apt_packages: + - openssh-server + - htop + - nano + - wget + - curl + - iperf3 + - tree + - tmux + - dnsutils + - iftop + - net-tools + tasks: + + # Set the timestamp to ensure it is the same across all tasks + - name: Generate static timestamp + set_fact: + timestamp: "{{ '%Y%m%d-%H%M%S' | strftime }}" + + #- name: Update apt repos + # apt: + # update_cache: yes + + #- name: Ensure required packages are installed + # apt: + # state: present + # name: + # - debootstrap + # - tar + + - name: Check if LXC container directory exists on host + stat: + path: "{{ working_lxc_dir }}" + register: lxc_dir_check + + - name: Ensure clean LXC container root filesystem on host + ignore_errors: yes + when: lxc_dir_check.stat.exists + command: + cmd: "rm -rf {{ working_lxc_dir }}" + + - name: Download and create LXC container root filesystem on host + command: + cmd: "debootstrap --arch=amd64 {{ debian_version }} {{ working_rootfs_dir }} https://deb.debian.org/debian/" + args: + creates: "{{ working_rootfs_dir }}" + + - name: Update apt in the container + command: + cmd: "{{ working_chroot }} /bin/bash -c 'apt update'" + + - name: Install additional packages in the container + command: + cmd: "{{ working_chroot }} /bin/bash -c 'DEBIAN_FRONTEND=noninteractive apt install -y {{ debian_apt_packages | join(' ') }}'" + + - name: Configure environment variables + template: + src: environment.j2 + dest: "{{ working_rootfs_dir }}/etc/environment" + + - name: Set up Message of the Day (MOTD) + template: + src: motd.j2 + dest: "{{ working_rootfs_dir }}/etc/motd" + + - name: Set Authorized SSH Keys + template: + src: authorized_keys.j2 + dest: "{{ working_rootfs_dir }}/root/.ssh/authorized_keys" + + - name: Create managed .bashrc file + template: + src: bash.bashrc.j2 + dest: "{{ working_rootfs_dir }}/etc/bash.bashrc" + + - name: Create .digrc file + template: + src: digrc.j2 + dest: "{{ working_rootfs_dir }}/root/.digrc" + + - name: Create locale file + template: + src: locale.j2 + dest: "{{ working_rootfs_dir }}/etc/default/locale" + + - name: Check if SSH configuration directory exists + stat: + path: "{{ working_rootfs_dir }}/etc/ssh/sshd_config.d" + register: ssh_config_dir_check + + - name: SSH Configuration + template: + src: sshd_config.j2 + dest: "{{ working_rootfs_dir }}/etc/ssh/sshd_config.d/fritzlab.conf" + when: ssh_config_dir_check.stat.exists + + - name: SSH Banner + template: + src: sshd_banner.j2 + dest: "{{ working_rootfs_dir }}/etc/ssh/banner.txt" + when: ssh_config_dir_check.stat.exists + + - name: Sysctl Configuration + template: + src: sysctl.j2 + dest: "{{ working_rootfs_dir }}/etc/sysctl.d/s99-fritzlab.conf" + + - name: Mask unnecessary systemd units + command: + cmd: "{{ working_chroot }} /bin/bash -c 'systemctl mask {{ lxc_unnecessary_units | join(' ') }}'" + + - name: Clean APT cache in the container + command: + cmd: "{{ working_chroot }} /bin/bash -c 'apt clean'" + + - name: Remove unnecessary locale files in the container + command: + cmd: "{{ working_chroot }} /bin/bash -c 'rm -rf /usr/share/locale/* /usr/share/man/* /usr/share/doc/*'" + + - name: Remove temporary files in the container + command: + cmd: "{{ working_chroot }} /bin/bash -c 'rm -rf /var/tmp/* /var/cache/* /tmp/*'" + + - name: Remove device files before archiving in the container + command: + cmd: "rm -rf {{ working_rootfs_dir }}/dev/*" + + - name: Create LXC image artifact by archiving rootfs on host + command: + cmd: "tar --exclude='./dev' --exclude='./dev/*' -czvf /tmp/{{ lxc_image_artifact_name }} -C {{ working_rootfs_dir }} ." + args: + creates: /tmp/{{ lxc_image_artifact_name }} + + - name: Move artifact to destination on host + command: + cmd: "mv /tmp/{{ lxc_image_artifact_name }} {{ lxc_template_dir }}" + + - name: Cleanup temporary artifact on host + file: + path: /tmp/{{ lxc_image_artifact_name }} + state: absent + + - name: Cleanup LXC container root filesystem on host + ignore_errors: yes + when: lxc_dir_check.stat.exists + command: + cmd: "rm -rf {{ working_lxc_dir }}" + + - name: Display LXC image artifact name + debug: + msg: "LXC Image Artifact Name: {{ lxc_image_artifact_name }}" + + + + + diff --git a/lxc/templates/authorized_keys.j2 b/lxc/templates/authorized_keys.j2 new file mode 100644 index 0000000..e7e41f6 --- /dev/null +++ b/lxc/templates/authorized_keys.j2 @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDKfPOnXImpSaSDzHLtlv6tenIdWhZEA15WWbkNCkM0u8q8eefJYMEkdT0F+46rilxjVnB0wmWcVUFmU8uT2YqfUczYb185LDKeSC5qQI/J+XibxeZNkE7swcTy9nj/dRqO2OpKPJnWUTQAUrgY7hmZYtOx8cjuQUvuRA1yBi5AuGFrHG0NKLr1h7AriLhkTv1xYAQ0W9wrG3hw882oLf1cLSAKWWhJX0XrlqKJQ5bqmt8yW3JO+Twdm2KDbxkR3IiHgpyfe9/zf5STMBejP2gXG0vpbRoVM9X10BtWDo22JudPEt2Wdy7qe7UqZLlNjHaYkUVTtN+JEf4ZoaBUf98t dfritz@desktops-mbp.corp.netflix.com diff --git a/lxc/templates/bash.bashrc.j2 b/lxc/templates/bash.bashrc.j2 new file mode 100644 index 0000000..c0f017b --- /dev/null +++ b/lxc/templates/bash.bashrc.j2 @@ -0,0 +1,51 @@ +# +# Add other environments, when available +# +if [ -f /fritzlab/environment ]; then + source /fritzlab/environment +fi +if [ -f /etc/os-release ]; then + source /etc/os-release +fi + +# +# Customize the Bash prompt with color-coded sections and fallback defaults. +# + +# colors +RED="\[\033[1;31m\]" # Bright red +GREEN="\[\033[1;32m\]" # Bright green +YELLOW="\[\033[1;33m\]" # Bright yellow +BLUE="\[\033[1;34m\]" # Bright blue +RESET="\[\033[0m\]" # Reset to default color + +# prompt parts +if [ -n "${ID}" ] && [ -n "${VERSION_ID}" ]; then + SYSTEM="${ID}${VERSION_ID}" +else + SYSTEM=$(uname -r) +fi +REGION="${FRITZLAB_REGION:-unknown}" +APP="${FRITZLAB_APP_NAME:-unknown}" +HOSTNAME=$(hostname) + +# prompt format +export PS1="${RED}${SYSTEM}${RESET} ${GREEN}${APP}${RESET} ${YELLOW}${REGION}${RESET} ${BLUE}${HOSTNAME}${RESET} \n(\u) \w \$ " + +# +# Set the history size and control options. +# +export HISTSIZE=1000 +export HISTFILESIZE=2000 +export HISTCONTROL=ignoredups:erasedups +shopt -s histappend + +# +# Set the default editor. +# +export TERM=xterm-256color + +# +# bash aliases +# +alias ll="ls -lFah" diff --git a/lxc/templates/digrc.j2 b/lxc/templates/digrc.j2 new file mode 100644 index 0000000..9ab7e02 --- /dev/null +++ b/lxc/templates/digrc.j2 @@ -0,0 +1 @@ +-t aaaa \ No newline at end of file diff --git a/lxc/templates/environment.j2 b/lxc/templates/environment.j2 new file mode 100644 index 0000000..a058709 --- /dev/null +++ b/lxc/templates/environment.j2 @@ -0,0 +1,4 @@ +FRITZLAB_IMAGE_DATE={{ timestamp }} +FRITZLAB_IMAGE_OS_NAME={{ debian_os }} +FRITZLAB_IMAGE_OS_VERSION={{ debian_version }} +FRITZLAB_IMAGE_TYPE=LXC \ No newline at end of file diff --git a/lxc/templates/locale.j2 b/lxc/templates/locale.j2 new file mode 100644 index 0000000..34edff5 --- /dev/null +++ b/lxc/templates/locale.j2 @@ -0,0 +1 @@ +LANG=C.UTF-8 \ No newline at end of file diff --git a/lxc/templates/motd.j2 b/lxc/templates/motd.j2 new file mode 100644 index 0000000..ef366a0 --- /dev/null +++ b/lxc/templates/motd.j2 @@ -0,0 +1,6 @@ + +************************************************************** +* WARNING: Unauthorized access to this system is prohibited. * +* Only intended and authorized personnel are permitted. * +* All activity is monitored and logged. * +************************************************************** diff --git a/lxc/templates/sshd_banner.j2 b/lxc/templates/sshd_banner.j2 new file mode 100644 index 0000000..ef366a0 --- /dev/null +++ b/lxc/templates/sshd_banner.j2 @@ -0,0 +1,6 @@ + +************************************************************** +* WARNING: Unauthorized access to this system is prohibited. * +* Only intended and authorized personnel are permitted. * +* All activity is monitored and logged. * +************************************************************** diff --git a/lxc/templates/sshd_config.j2 b/lxc/templates/sshd_config.j2 new file mode 100644 index 0000000..8f3a9ce --- /dev/null +++ b/lxc/templates/sshd_config.j2 @@ -0,0 +1,3 @@ +PermitRootLogin yes +PasswordAuthentication yes +Banner /etc/ssh/banner.txt \ No newline at end of file diff --git a/lxc/templates/sysctl.j2 b/lxc/templates/sysctl.j2 new file mode 100644 index 0000000..2821148 --- /dev/null +++ b/lxc/templates/sysctl.j2 @@ -0,0 +1,2 @@ +net.ipv6.conf.all.accept_dad=0 +net.ipv6.conf.default.accept_dad=0