diff --git a/all.yml b/all.yml new file mode 100644 index 0000000..62eb731 --- /dev/null +++ b/all.yml @@ -0,0 +1,16 @@ +--- +- hosts: lxd_host + roles: + - lxd_host + +#- hosts: containers +# roles: +# - webserver +# +#- hosts: freshrss +# roles: +# - freshrss +# +#- hosts: dokuwiki +# roles: +# - dokuwiki diff --git a/lxd_host_playbook.yml b/lxd_host_playbook.yml deleted file mode 100644 index eacb0ca..0000000 --- a/lxd_host_playbook.yml +++ /dev/null @@ -1,101 +0,0 @@ ---- -- name: top level play for lxd server provisioning - hosts: lxd_host - tags: install_lxd - tasks: - - name: include variables - include_vars: - file: site_vars.yml - - # TODO: use template for lxd-init --preseed - - name: copy ssh pubkey from controller to lxd host - copy: - src: "{{ lookup('env', 'HOME') + '/.ssh/id_rsa.pub' }}" - dest: "{{ tmp_pubkey }}" - - # TODO: might make sense to add a cache redirect for alpine packages - - include_tasks: tasks/container_common.yml - vars: - container_name: "{{ item.key }}" - container_sshd_port: "{{ item.value.sshd_port }}" - container_ip: "{{ item.value.ip }}" - tmp_sshd_config: "/tmp/sshd_config_{{ item.key }}" - with_items: "{{ containers | dict2items }}" - - -# -# container specific playbooks -# - -- import_playbook: tasks/dokuwiki.yml - -# -# DNAT routing -# - -# NOTE: do host routing last so we can fail on no sudo pass - -- name: add DNAT rules for ssh to containers - hosts: lxd_host - tags: dnat_route - tasks: - - include_vars: - file: site_vars.yml - - - name: install iptables and iptables-persistent - become: yes - apt: - name: [iptables, iptables-persistent] - state: present - - - name: add rules on containers - iptables: - table: nat - chain: PREROUTING - in_interface: "{{ host_iface }}" - protocol: tcp - match: tcp - source: "{{ host_cidr }}" - jump: DNAT - destination_port: "{{ item.value.sshd_port }}" - to_destination: "{{ item.value.ip }}" - become: yes - with_items: "{{ containers | dict2items }}" - - - name: save DNAT rules on lxd host - become: yes - community.general.iptables_state: - table: nat - state: saved - path: /etc/iptables/rules.v4 - -- name: add DNAT rules for individual containers - hosts: lxd_host - tags: dnat_route_2 - tasks: - - include_vars: - file: site_vars.yml - - - iptables: - table: nat - chain: PREROUTING - in_interface: "{{ host_iface }}" - protocol: tcp - match: tcp - source: "{{ host_cidr }}" - jump: DNAT - destination_port: "{{ hostvars['dokuwiki']['dnat_dest_port'] }}" - to_destination: "{{ hostvars['dokuwiki']['internal_ip'] }}" - become: yes - - - iptables: - table: nat - chain: PREROUTING - in_interface: "{{ host_iface }}" - protocol: tcp - match: tcp - source: "{{ host_cidr }}" - jump: DNAT - destination_port: "{{ hostvars['freshrss']['dnat_dest_port'] }}" - to_destination: "{{ hostvars['freshrss']['internal_ip'] }}" - become: yes diff --git a/role_test_playbook.yml b/role_test_playbook.yml deleted file mode 100644 index 06fa2eb..0000000 --- a/role_test_playbook.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -- hosts: lxd_containers - roles: - - webserver - -- hosts: freshrss - tags: freshrss - roles: - - freshrss diff --git a/tasks/dokuwiki.yml b/roles/dokuwiki/tasks/dokuwiki.yml similarity index 100% rename from tasks/dokuwiki.yml rename to roles/dokuwiki/tasks/dokuwiki.yml diff --git a/tasks/container_common.yml b/roles/lxd_host/tasks/container_install.yml similarity index 75% rename from tasks/container_common.yml rename to roles/lxd_host/tasks/container_install.yml index a208ade..d4952b1 100644 --- a/tasks/container_common.yml +++ b/roles/lxd_host/tasks/container_install.yml @@ -1,4 +1,17 @@ --- +- debug: + msg: | + container_ip: "{{ container_ip }}" + +- name: test if container is installed + command: "{{ lxc_cmd }} info {{ container_name }}" + ignore_errors: yes + register: command_return + +- set_fact: + container_present: true + when: command_return.rc == 0 + - name: "install container {{ container_name }}" community.general.lxd_container: name: "{{ container_name }}" @@ -17,41 +30,55 @@ nictype: bridged parent: "{{ lxd_bridge }}" ipv4.address: "{{ container_ip }}" + when: not container_present - name: update container packages command: "{{ lxc_cmd }} exec {{ container_name }} -- apk upgrade -U" + when: not container_present - name: install openssh, rsync, and shadow packages in containers command: "{{ lxc_cmd }} exec {{ container_name }} -- \ apk add openssh rsync shadow python3" + when: not container_present - name: "copy container sshd_config for {{ container_name }} to lxd host" template: src: templates/sshd_config.j2 dest: "{{ tmp_sshd_config }}" + when: not container_present - name: use lxc file push to get sshd_config into container command: "{{ lxc_cmd }} file push {{ tmp_sshd_config}} \ {{ container_name }}/etc/ssh/sshd_config" + when: not container_present - name: mkdir /root/.ssh in {{ container_name }} command: "{{ lxc_cmd }} exec {{ container_name }} -- mkdir -p /root/.ssh" + when: not container_present - name: add controller public key to {{ container_name }} authorized keys command: "{{ lxc_cmd }} file push {{ tmp_pubkey }} \ {{ container_name }}/root/.ssh/authorized_keys \ --gid 0 --uid 0 --mode 600" + when: not container_present - name: make hash of a random password set_fact: root_pass: "{{ lookup('password', '/dev/null length=15 chars=ascii_letters') | password_hash('sha512') }}" + when: not container_present - name: "set password to unlock root account (NOTE: still using pubkey only)" shell: '{{ lxc_cmd }} exec {{ container_name }} -- usermod -p {{ root_pass }} root' + when: not container_present - name: ensure sshd service is enabled command: "{{ lxc_cmd }} exec {{ container_name }} -- rc-update add sshd" + when: not container_present - name: ensure sshd service is started command: "{{ lxc_cmd }} exec {{ container_name }} -- rc-service sshd start" + when: not container_present + +- set_fact: + container_present: false diff --git a/roles/lxd_host/tasks/lxd_host.yml b/roles/lxd_host/tasks/lxd_host.yml new file mode 100644 index 0000000..1bed855 --- /dev/null +++ b/roles/lxd_host/tasks/lxd_host.yml @@ -0,0 +1,74 @@ +--- +# TODO: use template for lxd-init --preseed +- name: copy ssh pubkey from controller to lxd host + copy: + src: "{{ lookup('env', 'HOME') + '/.ssh/id_rsa.pub' }}" + dest: "{{ tmp_pubkey }}" + +# TODO: might make sense to add a cache redirect for alpine packages +- include_tasks: tasks/container_install.yml + tags: containers + vars: + container_name: "{{ item }}" + container_sshd_port: "{{ hostvars[item]['ansible_port'] }}" + container_ip: "{{ hostvars[item]['internal_ip'] }}" + tmp_sshd_config: "/tmp/sshd_config_{{ item }}" + with_items: "{{ groups['containers'] }}" + +- name: install iptables and iptables-persistent + tags: routing + become: yes + apt: + name: [iptables, iptables-persistent] + state: present + +- name: add DNAT rules for containers + tags: routing + iptables: + table: nat + chain: PREROUTING + in_interface: "{{ host_iface }}" + protocol: tcp + match: tcp + source: "{{ host_cidr }}" + jump: DNAT + destination_port: "{{ hostvars[item]['ansible_port'] }}" + to_destination: "{{ hostvars[item]['internal_ip'] }}" + become: yes + with_items: "{{ groups['containers'] }}" + +- name: save DNAT rules on lxd host + tags: routing + become: yes + community.general.iptables_state: + table: nat + state: saved + path: /etc/iptables/rules.v4 + +# TODO: add other dnat ports in above loop? +#- name: add dokuwiki DNAT routing +# iptables: +# table: nat +# chain: PREROUTING +# in_interface: "{{ host_iface }}" +# protocol: tcp +# match: tcp +# source: "{{ host_cidr }}" +# jump: DNAT +# destination_port: "{{ hostvars['dokuwiki']['dnat_dest_port'] }}" +# to_destination: "{{ hostvars['dokuwiki']['internal_ip'] }}" +# become: yes +# +#- name: add freshrss DNAT routing +# iptables: +# table: nat +# chain: PREROUTING +# in_interface: "{{ host_iface }}" +# protocol: tcp +# match: tcp +# source: "{{ host_cidr }}" +# jump: DNAT +# destination_port: "{{ hostvars['freshrss']['dnat_dest_port'] }}" +# to_destination: "{{ hostvars['freshrss']['internal_ip'] }}" +# become: yes + diff --git a/roles/lxd_host/tasks/main.yml b/roles/lxd_host/tasks/main.yml new file mode 100644 index 0000000..42ade99 --- /dev/null +++ b/roles/lxd_host/tasks/main.yml @@ -0,0 +1,12 @@ +--- +- import_tasks: lxd_host.yml + vars: + img_server: https://images.linuxcontainers.org + alp_img_alias: alpine/3.13/amd64 + lxc_cmd: /snap/bin/lxc + lxd_subnet_pfx: 10.98.46 + lxd_bridge: lxdbr0 + tmp_pubkey: /tmp/controller_key_rsa.pub + host_iface: enp2s0 + host_cidr: '192.168.11.0/24' + diff --git a/templates/sshd_config.j2 b/roles/lxd_host/templates/sshd_config.j2 similarity index 100% rename from templates/sshd_config.j2 rename to roles/lxd_host/templates/sshd_config.j2 diff --git a/roles/webserver/tasks/lighttpd.yml b/roles/webserver/tasks/lighttpd.yml index 6e2415f..6ff7dfe 100644 --- a/roles/webserver/tasks/lighttpd.yml +++ b/roles/webserver/tasks/lighttpd.yml @@ -1,7 +1,7 @@ --- - name: install lighttpd packages - vars: - packages: + apk: + name: - fcgi - lighttpd - php7-common @@ -30,8 +30,6 @@ - php7-zip # TODO: move tar to common packages - tar - apk: - name: "{{ packages | join(' ') }}" state: present - name: copy lighttpd.conf diff --git a/roles/webserver/templates/etc/lighttpd/lighttpd.conf.j2 b/roles/webserver/templates/etc/lighttpd/lighttpd.conf.j2 deleted file mode 100644 index 4b4b8be..0000000 --- a/roles/webserver/templates/etc/lighttpd/lighttpd.conf.j2 +++ /dev/null @@ -1,32 +0,0 @@ - -var.basedir = "/var/www/localhost" -var.logdir = "/var/log/lighttpd" -var.statedir = "/var/lib/lighttpd" - -server.modules = ( - "mod_access", - "mod_accesslog", - "mod_rewrite" -) - -include "mime-types.conf" -include "mod_fastcgi.conf" - -server.username = "lighttpd" -server.groupname = "lighttpd" -server.document-root = var.basedir + "/htdocs" -server.pid-file = "/run/lighttpd.pid" -server.errorlog = var.logdir + "/error.log" -server.indexfiles = ("index.php", "index.html", "index.htm", "default.htm") -server.follow-symlink = "enable" - -static-file.exclude-extensions = (".php", ".pl", ".cgi", ".fcgi") - -accesslog.filename = var.logdir + "/access.log" - -url.access-deny = ("~", ".inc") - -$HTTP["url"] =~ "^/dokuwiki/(data|conf|bin|inc|vendor)/+." { - url.access-deny = ("") -} - diff --git a/templates/lighttpd.conf.j2 b/roles/webserver/templates/lighttpd.conf.j2 similarity index 100% rename from templates/lighttpd.conf.j2 rename to roles/webserver/templates/lighttpd.conf.j2 diff --git a/site_vars.yml b/site_vars.yml deleted file mode 100644 index bbe2940..0000000 --- a/site_vars.yml +++ /dev/null @@ -1,22 +0,0 @@ ---- -img_server: https://images.linuxcontainers.org -alp_img_alias: alpine/3.13/amd64 -lxc_cmd: /snap/bin/lxc -lxd_subnet_pfx: 10.98.46 -lxd_bridge: lxdbr0 -tmp_pubkey: /tmp/controller_key_rsa.pub -host_iface: enp2s0 -host_cidr: '192.168.11.0/24' - -# TODO: move this info to inventory file -containers: - #- transmission - dokuwiki: - ip: "{{ lxd_subnet_pfx }}.100" - sshd_port: 2225 - freshrss: - ip: "{{ lxd_subnet_pfx }}.101" - sshd_port: 2226 - gitweb: - ip: "{{ lxd_subnet_pfx }}.102" - sshd_port: 2227