diff --git a/README.md b/README.md index c6ac781..aca27d5 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,37 @@ The `create.yaml` playbook will create a new vps if it doesn't exist yet and the `deploy.yaml` playbook will then use the hetzner cloud dynamic inventory to discover your vps. +### Hetzner cloud vps ipv6 only setup for jail+bridge operation + +Here's how: the major problem is, that Hetzner sends all traffic to +the mac of the primary interface. By default the bridge has another +one, thus it doesn't work. Also, I had ipv6 forwarding turned off, +which is required for this to work. + +Here's my setup: + +host rc.conf: +```default +ifconfig_vtnet0="DHCP" +cloned_interfaces="bridge0" +create_args_bridge0="inet6 auto_linklocal -ifdisabled addm vtnet0" +ifconfig_vtnet0="up -tso -vlanhwtso DHCP" +ifconfig_bridge0="DHCP" +ifconfig_bridge0_ipv6="inet6 2a01:4f8:c013:6513::1 prefixlen 64" +ipv6_defaultrouter="fe80::1%bridge0" +``` + +host sysctl.conf +```default +net.link.bridge.inherit_mac=1 +net.inet6.ip6.forwarding=1 +``` + +host /boot/loader.conf: +```default +if_bridge_load=YES +``` + ### Setup ansible - Create `group_vars/all/vars.yaml` with this content: diff --git a/TODO.md b/TODO.md index 893a753..d3b6a8a 100644 --- a/TODO.md +++ b/TODO.md @@ -32,3 +32,5 @@ or using e3 using wrapper script around `jaildk exec dns knotc ...` ## Add users with authorized_keys files ## Add quota config and enable/configure rctl + +## Fix jail DNS, doesn't work yet (pf missing?) diff --git a/deploy.yaml b/deploy.yaml index 56ff359..898523d 100644 --- a/deploy.yaml +++ b/deploy.yaml @@ -6,7 +6,7 @@ user: root roles: - role: server - - role: network + #- role: network - role: firewall - role: ssh - role: jails diff --git a/group_vars/all/all.yaml b/group_vars/all/all.yaml index 7813856..74612bd 100644 --- a/group_vars/all/all.yaml +++ b/group_vars/all/all.yaml @@ -13,7 +13,7 @@ packages: release: 14.1-RELEASE # snapshot to install in new vps -snapshot: FreeBSD-14.1-RELEASE-hcloud-init +snapshot: FreeBSD-14.1-RELEASE-p5-1-hcloud-init location: fsn1 @@ -39,11 +39,15 @@ storage: name: /crontabs +netif: + primary: bridge0 + kernel: sysctls: security.bsd.see_other_uids: 0 security.bsd.see_other_gids: 0 security.bsd.see_jail_proc: 0 + net.inet6.ip6.forwarding: 1 sysctlsoff: security.bsd.unprivileged_read_msgbuf: 0 security.bsd.unprivileged_proc_debug: 0 diff --git a/roles/firewall/templates/pf.conf.j2 b/roles/firewall/templates/pf.conf.j2 index 749e56d..67bc7fb 100644 --- a/roles/firewall/templates/pf.conf.j2 +++ b/roles/firewall/templates/pf.conf.j2 @@ -1,9 +1,23 @@ +# +# Look at past logs tcpdump -n -e -ttt -r /var/log/pflog +# Look at live logs (aka tail -f): tcpdump -n -e -ttt -i pflog0 +# +# Look at entries in table (SSH Limit Block): +# pfctl -t bad_hosts -T show +# Delete an ip from table: +# pfctl -t bad_hosts -T delete $ip + ext_if="{{ ansible_default_ipv6.interface }}" ### Default block policy is to return a reset packet -set block-policy return +set block-policy drop + +# fairness my ass +set optimization aggressive + ### Reassemble fragmented packets scrub in on $ext_if all fragment reassemble + ### Ignore loopback interface set skip on lo @@ -11,14 +25,22 @@ set skip on lo table persist ### Block on incoming traffic -block in all +block in log all ### Allow outgoing, skip others rules if match, and track connections pass out quick keep state +pass out inet6 keep state ### Block all incoming traffic from the $ext_if subnet which is not from $ext_if interface ### And block incoming traffic from $ext_if IP on $ext_if interface antispoof for $ext_if inet6 ### Allow SSH -pass in inet6 proto tcp from any to any port ssh flags S/SA keep state +table persist +pass in quick on $ext_if inet6 proto tcp from any to any port ssh \ + flags S/SAFR keep state \ + (max-src-conn-rate 10/60, \ + overload flush global) label ServicesTCP + +# ipv6 icmp +pass in quick inet6 proto icmp6 all keep state diff --git a/roles/jails/tasks/main.yaml b/roles/jails/tasks/main.yaml index d8c28cd..80737bb 100644 --- a/roles/jails/tasks/main.yaml +++ b/roles/jails/tasks/main.yaml @@ -37,5 +37,15 @@ regexp: '^(.*)quarterly(.*)$' replace: '\1latest\2' +- name: determine ipv6 address + shell: ifconfig {{ netif.primary }} inet6 | awk '{ if (/2a01/) { print $2 }}' + register: primaryip + +- name: setup bastille.conf + template: + src: bastille.conf.j2 + dest: /usr/local/etc/bastille/bastille.conf + # - name: update bootstrap # shell: "bastille update {{ release }}" + diff --git a/roles/jails/templates/bastille.conf.j2 b/roles/jails/templates/bastille.conf.j2 new file mode 100644 index 0000000..dfdc0af --- /dev/null +++ b/roles/jails/templates/bastille.conf.j2 @@ -0,0 +1,68 @@ +##################### +## [ BastilleBSD ] ## +##################### + +## default paths +bastille_prefix="/usr/local/bastille" ## default: "/usr/local/bastille" +bastille_backupsdir="${bastille_prefix}/backups" ## default: "${bastille_prefix}/backups" +bastille_cachedir="${bastille_prefix}/cache" ## default: "${bastille_prefix}/cache" +bastille_jailsdir="${bastille_prefix}/jails" ## default: "${bastille_prefix}/jails" +bastille_releasesdir="${bastille_prefix}/releases" ## default: "${bastille_prefix}/releases" +bastille_templatesdir="${bastille_prefix}/templates" ## default: "${bastille_prefix}/templates" +bastille_logsdir="/var/log/bastille" ## default: "/var/log/bastille" + +## pf configuration path +bastille_pf_conf="/etc/pf.conf" ## default: "/etc/pf.conf" + +## bastille scripts directory (assumed by bastille pkg) +bastille_sharedir="/usr/local/share/bastille" ## default: "/usr/local/share/bastille" + +## bootstrap archives, which components of the OS to install. +## base - The base OS, kernel + userland +## lib32 - Libraries for compatibility with 32 bit binaries +## ports - The FreeBSD ports (3rd party applications) tree +## src - The source code to the kernel + userland +## test - The FreeBSD test suite +## this is a whitespace separated list: +## bastille_bootstrap_archives="base lib32 ports src test" +bastille_bootstrap_archives="base" ## default: "base" + +## default timezone +bastille_tzdata="" ## default: empty to use host's time zone + +## default jail resolv.conf +bastille_resolv_conf="/etc/resolv.conf" ## default: "/etc/resolv.conf" + +## bootstrap urls +bastille_url_freebsd="http://ftp.freebsd.org/pub/FreeBSD/releases/" ## default: "http://ftp.freebsd.org/pub/FreeBSD/releases/" +bastille_url_hardenedbsd="https://installers.hardenedbsd.org/pub/" ## default: "https://installer.hardenedbsd.org/pub/HardenedBSD/releases/" +bastille_url_midnightbsd="https://www.midnightbsd.org/ftp/MidnightBSD/releases/" ## default: "https://www.midnightbsd.org/pub/MidnightBSD/releases/" + +## ZFS options +bastille_zfs_enable="YES" ## default: "" +bastille_zfs_zpool="zroot" ## default: "" +bastille_zfs_prefix="bastille" ## default: "${bastille_zfs_zpool}/bastille" +bastille_zfs_options="-o compress=lz4 -o atime=off" ## default: "-o compress=lz4 -o atime=off" + +## Export/Import options +bastille_compress_xz_options="-0 -v" ## default "-0 -v" +bastille_decompress_xz_options="-c -d -v" ## default "-c -d -v" +bastille_compress_gz_options="-1 -v" ## default "-1 -v" +bastille_decompress_gz_options="-k -d -c -v" ## default "-k -d -c -v" +bastille_export_options="" ## default "" predefined export options, e.g. "--safe --gz" + +## Networking +bastille_network_loopback="bastille0" ## default: "bastille0" +bastille_network_pf_ext_if="ext_if" ## default: "ext_if" +bastille_network_pf_table="jails" ## default: "jails" +bastille_network_shared="" ## default: "" +bastille_network_gateway="" ## default: "" +bastille_network_gateway6="{{ primaryip.stdout }}" ## default: "" + +## Default Templates +bastille_template_base="default/base" ## default: "default/base" +bastille_template_empty="" ## default: "default/empty" +bastille_template_thick="default/thick" ## default: "default/thick" +bastille_template_clone="default/clone" ## default: "default/clone" +bastille_template_thin="default/thin" ## default: "default/thin" +bastille_template_vnet="default/vnet" ## default: "default/vnet" diff --git a/roles/pubnix/tasks/main.yaml b/roles/pubnix/tasks/main.yaml index 6ba8a0c..ab73dd0 100644 --- a/roles/pubnix/tasks/main.yaml +++ b/roles/pubnix/tasks/main.yaml @@ -29,7 +29,7 @@ mountpoint: /data/home - name: determine ipv6 address - shell: ifconfig vtnet0 inet6 | awk '{ if (/2a01/) { sub(/::.$/, "::2", $2); print $2 }}' + shell: ifconfig {{ netif.primary }} inet6 | awk '{ if (/2a01/) { sub(/::.$/, "::2", $2); print $2 }}' register: jailip - name: create jail