diff --git a/ansible/environments/laptop/host_vars/odofreebsd b/ansible/environments/laptop/host_vars/odofreebsd index 294c60b..ba98b33 100644 --- a/ansible/environments/laptop/host_vars/odofreebsd +++ b/ansible/environments/laptop/host_vars/odofreebsd @@ -10,6 +10,7 @@ pflog_conf: network_rc: "odofreebsd_network.conf" rc_conf: "odofreebsd_rc.conf" loader_conf: "odofreebsd_loader.conf" +netgraph_config: "setup_netgraph_odo" graphics_driver: "intel" cputype: "intel" cpu_opt: tigerlake @@ -33,5 +34,13 @@ users: - backup_fido - homeassistant gitconfig: "gitconfig_home" -# devfs_rules: "odo_devfs.rules" -# devfs_system_ruleset: "localrules" +devfs_rules: "odo_devfs.rules" +jail_zfs_dataset: zroot/freebsd/release/jails +jail_zfs_dataset_mountpoint: /jail/main +jail_list: + - name: cloak + conf: + src: cloak + - name: dagger + conf: + src: dagger diff --git a/ansible/playbook.yaml b/ansible/playbook.yaml index d6bbd97..fb1182f 100644 --- a/ansible/playbook.yaml +++ b/ansible/playbook.yaml @@ -23,3 +23,4 @@ - firefox - devfs - ssh_client + - jail diff --git a/ansible/roles/base/tasks/freebsd.yaml b/ansible/roles/base/tasks/freebsd.yaml index 88a6e65..0b3dbc8 100644 --- a/ansible/roles/base/tasks/freebsd.yaml +++ b/ansible/roles/base/tasks/freebsd.yaml @@ -2,6 +2,7 @@ package: name: - pstree + - gsed state: present - name: See if the alacritty termcap has been added diff --git a/ansible/roles/devfs/files/odo_devfs.rules b/ansible/roles/devfs/files/odo_devfs.rules index 273e8a1..6797aad 100644 --- a/ansible/roles/devfs/files/odo_devfs.rules +++ b/ansible/roles/devfs/files/odo_devfs.rules @@ -1,3 +1,13 @@ [localrules=10] add path 'input/*' mode 0660 group video add path 'usb/*' mode 0660 group usb + +[tajailwg=13] +add include $devfsrules_hide_all +add include $devfsrules_unhide_basic +add include $devfsrules_unhide_login +add path 'bpf*' unhide +add path pf unhide +add path pflog unhide +add path pfsynv unhide +add path 'tun*' unhide diff --git a/ansible/roles/firewall/files/odofreebsd_pf.conf b/ansible/roles/firewall/files/odofreebsd_pf.conf index fa5f23c..f7649ff 100644 --- a/ansible/roles/firewall/files/odofreebsd_pf.conf +++ b/ansible/roles/firewall/files/odofreebsd_pf.conf @@ -1,7 +1,8 @@ ext_if = "{ igb0 igb1 ix0 ix1 wlan0 }" +jail_net_v4 = "10.193.223.0/24" dhcp = "{ bootpc, bootps }" -# allow = "{ }" +# allow = "{ host_uplink0 }" tcp_pass_in = "{ 22 }" udp_pass_in = "{ 53 51820 }" @@ -12,9 +13,13 @@ udp_pass_in = "{ 53 51820 }" set skip on lo # redirections +nat on $ext_if inet from $jail_net_v4 to { any, !$jail_net_v4 } tag ALLOWED -> (wlan0) + +rdr on host_uplink0 inet proto {tcp, udp} from any to 10.193.223.1 port 53 tag ALLOWED -> 1.1.1.1 port 53 # filtering block log all +pass quick on $ext_if tagged ALLOWED pass out on $ext_if # We pass on the interfaces listed in allow rather than skipping on @@ -31,3 +36,5 @@ pass in on $ext_if proto tcp to any port $tcp_pass_in pass in on $ext_if proto udp to any port $udp_pass_in pass quick on $ext_if proto udp from any port $dhcp to any port $dhcp + +pass in on host_uplink0 proto udp from any to any port { 53 51820 } diff --git a/ansible/roles/jail/defaults/main.yaml b/ansible/roles/jail/defaults/main.yaml new file mode 100644 index 0000000..7c6d77d --- /dev/null +++ b/ansible/roles/jail/defaults/main.yaml @@ -0,0 +1 @@ +jail_list: [] diff --git a/ansible/roles/jail/files/jails/cloak.conf b/ansible/roles/jail/files/jails/cloak.conf new file mode 100644 index 0000000..181974f --- /dev/null +++ b/ansible/roles/jail/files/jails/cloak.conf @@ -0,0 +1,12 @@ +cloak { + path = "/jail/main/jails/cloak"; + vnet; + vnet.interface += "host_link2"; + vnet.interface += "wg_uplink0"; + devfs_ruleset = 13; + mount.devfs; # To expose tun device + + exec.start += "/bin/sh /etc/rc"; + exec.stop = "/bin/sh /etc/rc.shutdown jail"; + exec.consolelog = "/var/log/jail_${name}_console.log"; +} diff --git a/ansible/roles/jail/files/jails/dagger.conf b/ansible/roles/jail/files/jails/dagger.conf new file mode 100644 index 0000000..cab230e --- /dev/null +++ b/ansible/roles/jail/files/jails/dagger.conf @@ -0,0 +1,9 @@ +dagger { + path = "/jail/main/jails/dagger"; + vnet; + vnet.interface += "wg_link2"; + + exec.start += "/bin/sh /etc/rc"; + exec.stop = "/bin/sh /etc/rc.shutdown jail"; + exec.consolelog = "/var/log/jail_${name}_console.log"; +} diff --git a/ansible/roles/jail/files/setup_netgraph b/ansible/roles/jail/files/setup_netgraph new file mode 100644 index 0000000..e6bc224 --- /dev/null +++ b/ansible/roles/jail/files/setup_netgraph @@ -0,0 +1,23 @@ +#!/bin/sh +# /usr/local/etc/rc.d/setup_netgraph +# +# REQUIRE: FILESYSTEM kld +# PROVIDE: setup_netgraph +# BEFORE: netif + +. /etc/rc.subr +name=setup_netgraph +rcvar=${name}_enable +start_cmd="${name}_start" +stop_cmd="${name}_stop" +load_rc_config $name + +setup_netgraph_start() { + /usr/local/bin/setup_netgraph start +} + +setup_netgraph_stop() { + /usr/local/bin/setup_netgraph stop +} + +run_rc_command "$1" diff --git a/ansible/roles/jail/files/setup_netgraph_odo b/ansible/roles/jail/files/setup_netgraph_odo new file mode 100644 index 0000000..7ed26c9 --- /dev/null +++ b/ansible/roles/jail/files/setup_netgraph_odo @@ -0,0 +1,63 @@ +#!/usr/local/bin/bash + +cleanup() { + ngctl shutdown host_link2: + ngctl shutdown host_uplink0: + ngctl shutdown host_bridge0: + ngctl shutdown wg_link2: + ngctl shutdown wg_uplink0: + ngctl shutdown wg_bridge0: +} + +setup_netgraph_start() { + cleanup + + ngctl -d -f - <&2 echo "Unrecognized command" +fi diff --git a/ansible/roles/jail/meta/main.yaml b/ansible/roles/jail/meta/main.yaml new file mode 100644 index 0000000..b5b170a --- /dev/null +++ b/ansible/roles/jail/meta/main.yaml @@ -0,0 +1,2 @@ +dependencies: + - devfs # To expose /dev entries like tun for wireguard diff --git a/ansible/roles/jail/tasks/common.yaml b/ansible/roles/jail/tasks/common.yaml new file mode 100644 index 0000000..d7c1735 --- /dev/null +++ b/ansible/roles/jail/tasks/common.yaml @@ -0,0 +1,14 @@ +- import_tasks: tasks/freebsd.yaml + when: 'os_flavor == "freebsd"' + +- import_tasks: tasks/linux.yaml + when: 'os_flavor == "linux"' + +- include_tasks: + file: tasks/peruser.yaml + apply: + become: yes + become_user: "{{ initialize_user }}" + loop: "{{ users | dict2items | community.general.json_query('[?value.initialize==`true`].key') }}" + loop_control: + loop_var: initialize_user diff --git a/ansible/roles/jail/tasks/freebsd.yaml b/ansible/roles/jail/tasks/freebsd.yaml new file mode 100644 index 0000000..e2b7e6e --- /dev/null +++ b/ansible/roles/jail/tasks/freebsd.yaml @@ -0,0 +1,136 @@ +- name: Create common zfs datasets + zfs: + name: "{{ item }}" + state: present + extra_zfs_properties: + mountpoint: "none" + loop: "{{ ((jail_list | community.general.json_query('[*].dataset')) + [jail_zfs_dataset]) | product(['', '/persistent', '/jails']) | map('join', '') }}" + +- name: Create jail zfs datasets + zfs: + name: "{{ item.dataset|default(jail_zfs_dataset) }}/jails/{{ item.name }}" + state: present + extra_zfs_properties: '{{ {''mountpoint'': item.dataset_mountpoint|default(jail_zfs_dataset_mountpoint) + "/jails/" + item.name}|combine(item.properties|default({})) }}' + + loop: "{{ jail_list }}" + +- name: Create persistent jail zfs datasets + zfs: + name: "{{ item.dataset|default(jail_zfs_dataset) }}/persistent/{{ item.name }}" + state: present + extra_zfs_properties: + mountpoint: "none" + when: item.persist|default([])|length > 0 + loop: "{{ jail_list }}" + +- name: Create jail specific zfs datasets + zfs: + name: "{{ item.0.dataset|default(jail_zfs_dataset) }}/persistent/{{ item.0.name }}/{{ item.1.name }}" + state: present + extra_zfs_properties: '{{ {''mountpoint'': item.0.dataset_mountpoint|default(jail_zfs_dataset_mountpoint) + "/jails/" + item.0.name + item.1.mount }|combine(item.1.properties|default({})) }}' + loop: "{{ jail_list|subelements('persist', skip_missing=True) }}" + +- name: Install scripts + template: + src: "templates/{{ item.src }}.j2" + dest: "{{ item.dest }}" + mode: 0755 + owner: root + group: wheel + loop: + - src: new_jail.bash + dest: /usr/local/bin/new_jail + +- name: Install config files + copy: + src: "files/{{ item.fstab }}" + dest: '{{ item.fstab_dest|default("/etc/fstab." + item.name) }}' + mode: 0644 + owner: root + group: wheel + when: item.fstab is defined + loop: "{{ jail_list }}" + +- name: Install persistent files + copy: + src: "files/{{ item.1.src }}" + dest: "{{ item.0.dataset_mountpoint|default(jail_zfs_dataset_mountpoint) }}/jails/{{ item.0.name }}{{ item.1.dest }}" + mode: '{{ item.1.mode|default("0644") }}' + owner: root + group: wheel + loop: "{{ jail_list|subelements('files', skip_missing=True) }}" + +- name: Install jail.conf files + when: item.conf.src is defined + copy: + src: "files/jails/{{ item.conf.src }}.conf" + dest: "/etc/jail.conf.d/{{ item.conf.dest|default(item.conf.src) }}.conf" + mode: "0644" + owner: root + group: wheel + loop: "{{ jail_list }}" + +- name: Enable Jails + community.general.sysrc: + name: jail_enable + value: "YES" + path: /etc/rc.conf.d/jail + when: jail_list|community.general.json_query('[?enabled==`true`]')|length > 0 + +- name: Set enabled jail list + community.general.sysrc: + name: jail_list + value: "{{ jail_list|community.general.json_query('[?enabled==`true`].name')|join(' ') }}" + path: /etc/rc.conf.d/jail + when: jail_list|community.general.json_query('[?enabled==`true`]')|length > 0 + +- name: Disable Jails + file: + path: /etc/rc.conf.d/jail + state: absent + when: jail_list|community.general.json_query('[?enabled==`true`]')|length == 0 + +- name: Install rc script + when: netgraph_config is defined + copy: + src: "files/{{ item.src }}" + dest: "/usr/local/etc/rc.d/{{ item.dest|default(item.src) }}" + owner: root + group: wheel + mode: 0755 + loop: + - src: setup_netgraph + +- name: Install scripts + when: netgraph_config is defined + copy: + src: "files/{{ item.src }}" + dest: "{{ item.dest }}" + mode: 0755 + owner: root + group: wheel + loop: + - src: "{{ netgraph_config }}" + dest: /usr/local/bin/setup_netgraph + +- name: Enable setup_netgraph + when: netgraph_config is defined + community.general.sysrc: + name: setup_netgraph_enable + value: "YES" + path: /etc/rc.conf.d/setup_netgraph + +- name: Disable setup_netgraph + when: netgraph_config is not defined + file: + path: /etc/rc.conf.d/setup_netgraph + state: absent + +- name: Enable gateway + community.general.sysrc: + name: "{{ item }}" + value: "YES" + path: /etc/rc.conf.d/routing + loop: + - gateway_enable + - ipv6_gateway_enable diff --git a/ansible/roles/jail/tasks/linux.yaml b/ansible/roles/jail/tasks/linux.yaml new file mode 100644 index 0000000..e1835f0 --- /dev/null +++ b/ansible/roles/jail/tasks/linux.yaml @@ -0,0 +1,6 @@ +# - name: Install packages +# pacman: +# name: +# - foo +# state: present +# update_cache: true diff --git a/ansible/roles/jail/tasks/main.yaml b/ansible/roles/jail/tasks/main.yaml new file mode 100644 index 0000000..b7fbdd3 --- /dev/null +++ b/ansible/roles/jail/tasks/main.yaml @@ -0,0 +1,2 @@ +- import_tasks: tasks/common.yaml + when: jail_zfs_dataset is defined and jail_zfs_dataset_mountpoint is defined diff --git a/ansible/roles/jail/tasks/peruser.yaml b/ansible/roles/jail/tasks/peruser.yaml new file mode 100644 index 0000000..111e886 --- /dev/null +++ b/ansible/roles/jail/tasks/peruser.yaml @@ -0,0 +1,29 @@ +- include_role: + name: per_user + +# - name: Create directories +# file: +# name: "{{ account_homedir.stdout }}/{{ item }}" +# state: directory +# mode: 0700 +# owner: "{{ account_name.stdout }}" +# group: "{{ group_name.stdout }}" +# loop: +# - ".config/foo" + +# - name: Copy files +# copy: +# src: "files/{{ item.src }}" +# dest: "{{ account_homedir.stdout }}/{{ item.dest }}" +# mode: 0600 +# owner: "{{ account_name.stdout }}" +# group: "{{ group_name.stdout }}" +# loop: +# - src: foo.conf +# dest: .config/foo/foo.conf + +- import_tasks: tasks/peruser_freebsd.yaml + when: 'os_flavor == "freebsd"' + +- import_tasks: tasks/peruser_linux.yaml + when: 'os_flavor == "linux"' diff --git a/ansible/roles/jail/tasks/peruser_freebsd.yaml b/ansible/roles/jail/tasks/peruser_freebsd.yaml new file mode 100644 index 0000000..e69de29 diff --git a/ansible/roles/jail/tasks/peruser_linux.yaml b/ansible/roles/jail/tasks/peruser_linux.yaml new file mode 100644 index 0000000..e69de29 diff --git a/ansible/roles/jail/templates/new_jail.bash.j2 b/ansible/roles/jail/templates/new_jail.bash.j2 new file mode 100644 index 0000000..619fa38 --- /dev/null +++ b/ansible/roles/jail/templates/new_jail.bash.j2 @@ -0,0 +1,40 @@ +#!/usr/bin/env bash +# +# Create a new jail +set -euo pipefail +IFS=$'\n\t' +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +: ${JAIL_MOUNTPOINT:="{{ jail_zfs_dataset_mountpoint }}/jails"} + +function die { + echo >&2 "$@" + exit 1 +} + +[ "$#" -eq 2 ] || die "1 argument required, $# provided" + +JAIL_NAME="$2" +export DESTDIR="${JAIL_MOUNTPOINT}/$JAIL_NAME" + +function by_src { + cd /usr/src + make -j 16 buildworld + make installworld DESTDIR=$DESTDIR + make distribution DESTDIR=$DESTDIR +} + +function by_bin { + DESTRELEASE=13.1-RELEASE + DESTARCH=`uname -m` + SOURCEURL=http://ftp.freebsd.org/pub/FreeBSD/releases/$DESTARCH/$DESTRELEASE/ + for component in base ports; do fetch $SOURCEURL/$component.txz -o - | tar -xf - -C "$DESTDIR" ; done +} + +if [ "$1" = "src" ]; then + by_src +elif [ "$1" = "bin" ]; then + by_bin +else + die "First argument must be either 'src' or 'bin', got $1" +fi