├── cbsd-profile ├── skel │ ├── etc │ │ ├── motd │ │ ├── make.conf │ │ ├── pwd.db │ │ ├── rc.conf │ │ ├── spwd.db │ │ ├── mail │ │ │ ├── aliases.db │ │ │ └── aliases │ │ ├── group │ │ ├── crontab │ │ ├── passwd │ │ └── master.passwd │ ├── root │ │ ├── .bashrc │ │ └── .cshrc │ └── usr │ │ └── home │ │ └── provision │ │ ├── .history │ │ ├── .login_conf │ │ ├── .login │ │ ├── .rhosts │ │ ├── .mailrc │ │ ├── .mail_aliases │ │ ├── .profile │ │ ├── .shrc │ │ └── .cshrc ├── system │ ├── clone.d │ │ └── placeholder │ ├── create.d │ │ └── placeholder │ ├── facts.d │ │ ├── placeholder │ │ └── reggae_ip │ ├── remove.d │ │ └── placeholder │ ├── rename.d │ │ └── placeholder │ ├── start.d │ │ └── placeholder │ ├── stop.d │ │ └── placeholder │ ├── clone-local.d │ │ └── placeholder │ ├── master_create.d │ │ └── placeholder │ ├── master_poststart.d │ │ └── placeholder │ ├── master_poststop.d │ │ └── placeholder │ ├── master_prestart.d │ │ └── placeholder │ └── master_prestop.d │ │ └── placeholder └── jail-freebsd-reggae.conf ├── skel ├── ansible │ ├── ansible │ │ ├── roles │ │ │ └── .keep │ │ ├── inventory │ │ │ └── .keep │ │ └── group_vars │ │ │ └── .keep │ ├── requirements.yml │ └── templates │ │ └── site.yml.tpl ├── salt │ └── salt │ │ └── states │ │ ├── top.sls │ │ └── core.sls ├── puppet │ └── puppet │ │ └── manifests │ │ └── site.pp ├── chef │ └── chef │ │ └── cookbooks │ │ └── core │ │ └── recipes │ │ └── default.rb └── shell │ └── shell │ └── provision.sh ├── .gitignore ├── templates ├── rtsold ├── network ├── gitignore.project ├── ansible │ ├── group_vars │ │ └── all.tpl │ ├── inventory.local.tpl │ └── inventory.remote.tpl ├── rtadvd.conf ├── master.fstab ├── netif ├── cloud-init │ ├── meta-data │ └── user-data ├── network-jail.conf ├── dhcpd-hook.sh ├── Makefile.service ├── nsd.conf ├── unbound_control.conf ├── install-packages.sh ├── mount-project.sh ├── xorg.sh ├── Makefile.project ├── devfs.rules ├── gitignore ├── resolvconf.conf ├── unbound_reggae.conf ├── ip-by-mac.sh ├── setup-vm.sh ├── freebsd-update.conf ├── cloud-initial.sh ├── export-ports.sh ├── unbound.conf ├── pf-jail.conf ├── initenv.conf ├── base-jail.conf ├── pf.conf ├── cloud-devops.sh ├── dhcpd.conf ├── cbsd.conf.tpl ├── cbsd-vnet.conf.tpl ├── master.conf ├── linux.conf.tpl ├── pkg.conf ├── dhcpd6.conf ├── cbsd-bhyve.freebsd.conf.tpl └── reggae-register.sh ├── mk ├── frameworks │ ├── freenit.project.mk │ └── freenit.service.mk ├── jail-service.mk ├── chef.mk ├── salt.mk ├── shell.mk ├── puppet.mk ├── common.mk ├── service.mk ├── use.mk ├── ansible.mk ├── base-jail.mk ├── bhyve-service.mk ├── project.mk └── cbsd-jail.mk ├── scripts ├── read-pass.sh ├── version.sh ├── network-init.sh ├── project-init.sh ├── bhyve-init.sh ├── backend-init.sh ├── get-config.sh ├── pf.sh ├── start.sh ├── stop.sh ├── export.sh ├── expect-run.sh ├── base-init.sh ├── get-ip.sh ├── rmjail.sh ├── ssh.sh ├── scp.sh ├── ssh-ping.sh ├── default.conf ├── shell-provision.sh ├── jexec.sh ├── update-profiles.sh ├── apply-proxy.sh ├── init.sh ├── puppet-provision.sh ├── chef-provision.sh ├── service.sh ├── utils.sh ├── update-base.sh ├── salt-provision.sh ├── pkg-upgrade.sh ├── import.sh ├── cbsd-init.sh ├── base-network-init.sh ├── host-init.sh ├── cbsd-network-init.sh └── mkjail.sh ├── doc ├── base │ └── README.md ├── provisioners │ ├── README.md │ ├── shell.md │ ├── puppet.md │ ├── chef.md │ ├── salt.md │ └── ansible.md ├── README.md └── cbsd │ └── README.md ├── id_rsa.pub ├── reggae.conf.sample ├── bin └── reggae ├── LICENSE ├── id_rsa ├── README.md ├── Makefile └── man └── reggae.1 /cbsd-profile/skel/etc/motd: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /skel/ansible/ansible/roles/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /skel/ansible/ansible/inventory/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin/conf.sh 2 | man/*.1.gz 3 | -------------------------------------------------------------------------------- /skel/ansible/ansible/group_vars/.keep: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /templates/rtsold: -------------------------------------------------------------------------------- 1 | rtsold_enable="YES" 2 | -------------------------------------------------------------------------------- /templates/network: -------------------------------------------------------------------------------- 1 | dhclient_program="DHCP" 2 | -------------------------------------------------------------------------------- /cbsd-profile/skel/etc/make.conf: -------------------------------------------------------------------------------- 1 | WRKDIRPREFIX=/tmp 2 | -------------------------------------------------------------------------------- /templates/gitignore.project: -------------------------------------------------------------------------------- 1 | services/ 2 | vars.mk 3 | -------------------------------------------------------------------------------- /templates/ansible/group_vars/all.tpl: -------------------------------------------------------------------------------- 1 | service: SERVICE 2 | -------------------------------------------------------------------------------- /skel/ansible/requirements.yml: -------------------------------------------------------------------------------- 1 | - onelove-roles.freebsd-common 2 | -------------------------------------------------------------------------------- /skel/salt/salt/states/top.sls: -------------------------------------------------------------------------------- 1 | base: 2 | '*': 3 | - core 4 | -------------------------------------------------------------------------------- /templates/rtadvd.conf: -------------------------------------------------------------------------------- 1 | INTERFACE:addr="IPV6_PREFIX:":raflags="mo" 2 | -------------------------------------------------------------------------------- /skel/salt/salt/states/core.sls: -------------------------------------------------------------------------------- 1 | tmux: 2 | pkg: 3 | - installed 4 | -------------------------------------------------------------------------------- /templates/ansible/inventory.local.tpl: -------------------------------------------------------------------------------- 1 | SERVICE ansible_connection=jail 2 | -------------------------------------------------------------------------------- /templates/master.fstab: -------------------------------------------------------------------------------- 1 | /var/run/reggae /var/run/reggae nullfs rw 0 0 2 | -------------------------------------------------------------------------------- /cbsd-profile/skel/root/.bashrc: -------------------------------------------------------------------------------- 1 | export PS1='\[\e[1;31m\][\u@\h \W]\$\[\e[0m\] ' 2 | -------------------------------------------------------------------------------- /templates/netif: -------------------------------------------------------------------------------- 1 | ifconfig_eth0_ipv6="inet6 -ifdisabled auto_linklocal accept_rtadv" 2 | -------------------------------------------------------------------------------- /templates/cloud-init/meta-data: -------------------------------------------------------------------------------- 1 | --- 2 | instance-id: SERVICE 3 | local-hostname: SERVICE.DOMAIN 4 | -------------------------------------------------------------------------------- /cbsd-profile/skel/etc/pwd.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbsd/reggae/HEAD/cbsd-profile/skel/etc/pwd.db -------------------------------------------------------------------------------- /cbsd-profile/skel/usr/home/provision/.history: -------------------------------------------------------------------------------- 1 | #+1512601899 2 | ls -l 3 | #+1512601900 4 | ls -al 5 | -------------------------------------------------------------------------------- /cbsd-profile/skel/etc/rc.conf: -------------------------------------------------------------------------------- 1 | sshd_enable="YES" 2 | syslogd_flags="-ss -c" 3 | sendmail_enable="NONE" 4 | -------------------------------------------------------------------------------- /cbsd-profile/skel/etc/spwd.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbsd/reggae/HEAD/cbsd-profile/skel/etc/spwd.db -------------------------------------------------------------------------------- /mk/frameworks/freenit.project.mk: -------------------------------------------------------------------------------- 1 | .if !target(collect) 2 | collect: up 3 | @bin/collect.sh 4 | .endif 5 | -------------------------------------------------------------------------------- /templates/network-jail.conf: -------------------------------------------------------------------------------- 1 | network { 2 | $id = 0; 3 | .include "/etc/jail.conf.d/reggae.inc"; 4 | } 5 | -------------------------------------------------------------------------------- /skel/puppet/puppet/manifests/site.pp: -------------------------------------------------------------------------------- 1 | file { 2 | '/tmp/reggae': 3 | content => "hello, world!\n", 4 | } 5 | 6 | -------------------------------------------------------------------------------- /cbsd-profile/skel/etc/mail/aliases.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbsd/reggae/HEAD/cbsd-profile/skel/etc/mail/aliases.db -------------------------------------------------------------------------------- /scripts/read-pass.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo -n "Password: " >&2; stty -echo; read passwd; stty echo; echo ${passwd} 4 | -------------------------------------------------------------------------------- /scripts/version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | SCRIPT_DIR=$(dirname $0) 4 | . "${SCRIPT_DIR}/default.conf" 5 | 6 | echo "${VERSION}" 7 | -------------------------------------------------------------------------------- /skel/chef/chef/cookbooks/core/recipes/default.rb: -------------------------------------------------------------------------------- 1 | file "/tmp/reggae" do 2 | content 'This file was created by Chef!' 3 | end 4 | -------------------------------------------------------------------------------- /skel/shell/shell/provision.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo -n "Reggae shell provisioner running as " 4 | id 5 | 6 | echo I am ${0} 7 | -------------------------------------------------------------------------------- /templates/dhcpd-hook.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | lockf /tmp/cbsd.zone.lock /usr/local/bin/reggae-register.sh "$1" "$2" "$3" "$4" "$5" 4 | -------------------------------------------------------------------------------- /templates/ansible/inventory.remote.tpl: -------------------------------------------------------------------------------- 1 | SERVICE ansible_ssh_user=provision ansible_ssh_private_key_file=/usr/local/share/reggae/id_rsa 2 | -------------------------------------------------------------------------------- /templates/Makefile.service: -------------------------------------------------------------------------------- 1 | SERVICE = SERVICE_NAME 2 | REGGAE_PATH := /usr/local/share/reggae 3 | 4 | .include <${REGGAE_PATH}/mk/service.mk> 5 | -------------------------------------------------------------------------------- /scripts/network-init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | BACKEND=${BACKEND:="base"} 4 | SCRIPT_DIR=$(dirname $0) 5 | "${SCRIPT_DIR}/${BACKEND}-network-init.sh" 6 | -------------------------------------------------------------------------------- /templates/nsd.conf: -------------------------------------------------------------------------------- 1 | server: 2 | zonesdir: "/usr/local/etc/nsd/zones" 3 | 4 | remote-control: 5 | control-enable: yes 6 | control-interface: lo0 7 | -------------------------------------------------------------------------------- /templates/unbound_control.conf: -------------------------------------------------------------------------------- 1 | remote-control: 2 | control-enable: yes 3 | control-use-cert: no 4 | control-interface: /var/unbound/local.ctl 5 | -------------------------------------------------------------------------------- /mk/jail-service.mk: -------------------------------------------------------------------------------- 1 | CONFIGURED_BACKEND != reggae get-config BACKEND 2 | BACKEND ?= ${CONFIGURED_BACKEND} 3 | 4 | .include <${REGGAE_PATH}/mk/${BACKEND}-jail.mk> 5 | -------------------------------------------------------------------------------- /templates/install-packages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | trap "rm -rf ${0}" HUP INT ABRT BUS TERM EXIT 4 | 5 | if [ -z "${1}" ]; then 6 | exit 0 7 | fi 8 | mdo pkg install -y ${@} 9 | -------------------------------------------------------------------------------- /cbsd-profile/system/clone.d/placeholder: -------------------------------------------------------------------------------- 1 | # place here executable command or script or links to executable files 2 | # you can use CBSD jail/vm-related variables from environment 3 | 4 | -------------------------------------------------------------------------------- /cbsd-profile/system/create.d/placeholder: -------------------------------------------------------------------------------- 1 | # place here executable command or script or links to executable files 2 | # you can use CBSD jail/vm-related variables from environment 3 | 4 | -------------------------------------------------------------------------------- /cbsd-profile/system/facts.d/placeholder: -------------------------------------------------------------------------------- 1 | # place here executable command or script or links to executable files 2 | # you can use CBSD jail/vm-related variables from environment 3 | 4 | -------------------------------------------------------------------------------- /cbsd-profile/system/remove.d/placeholder: -------------------------------------------------------------------------------- 1 | # place here executable command or script or links to executable files 2 | # you can use CBSD jail/vm-related variables from environment 3 | 4 | -------------------------------------------------------------------------------- /cbsd-profile/system/rename.d/placeholder: -------------------------------------------------------------------------------- 1 | # place here executable command or script or links to executable files 2 | # you can use CBSD jail/vm-related variables from environment 3 | 4 | -------------------------------------------------------------------------------- /cbsd-profile/system/start.d/placeholder: -------------------------------------------------------------------------------- 1 | # place here executable command or script or links to executable files 2 | # you can use CBSD jail/vm-related variables from environment 3 | 4 | -------------------------------------------------------------------------------- /cbsd-profile/system/stop.d/placeholder: -------------------------------------------------------------------------------- 1 | # place here executable command or script or links to executable files 2 | # you can use CBSD jail/vm-related variables from environment 3 | 4 | -------------------------------------------------------------------------------- /cbsd-profile/system/clone-local.d/placeholder: -------------------------------------------------------------------------------- 1 | # place here executable command or script or links to executable files 2 | # you can use CBSD jail/vm-related variables from environment 3 | 4 | -------------------------------------------------------------------------------- /cbsd-profile/system/master_create.d/placeholder: -------------------------------------------------------------------------------- 1 | # place here executable command or script or links to executable files 2 | # you can use CBSD jail/vm-related variables from environment 3 | 4 | -------------------------------------------------------------------------------- /cbsd-profile/system/master_poststart.d/placeholder: -------------------------------------------------------------------------------- 1 | # place here executable command or script or links to executable files 2 | # you can use CBSD jail/vm-related variables from environment 3 | 4 | -------------------------------------------------------------------------------- /cbsd-profile/system/master_poststop.d/placeholder: -------------------------------------------------------------------------------- 1 | # place here executable command or script or links to executable files 2 | # you can use CBSD jail/vm-related variables from environment 3 | 4 | -------------------------------------------------------------------------------- /cbsd-profile/system/master_prestart.d/placeholder: -------------------------------------------------------------------------------- 1 | # place here executable command or script or links to executable files 2 | # you can use CBSD jail/vm-related variables from environment 3 | 4 | -------------------------------------------------------------------------------- /cbsd-profile/system/master_prestop.d/placeholder: -------------------------------------------------------------------------------- 1 | # place here executable command or script or links to executable files 2 | # you can use CBSD jail/vm-related variables from environment 3 | 4 | -------------------------------------------------------------------------------- /scripts/project-init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cp /usr/local/share/reggae/templates/Makefile.project Makefile 4 | cp /usr/local/share/reggae/templates/gitignore.project .gitignore 5 | mkdir services 6 | -------------------------------------------------------------------------------- /templates/mount-project.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | trap "rm -rf ${0}" HUP INT ABRT BUS TERM EXIT 4 | 5 | if [ ! -e /usr/src/Makefile ]; then 6 | mdo mount -t nfs INTERFACE_IP:${1} /usr/src 7 | fi 8 | -------------------------------------------------------------------------------- /templates/xorg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | X_ENABLED="XORG" 4 | DOMAIN=`reggae get-config DOMAIN` 5 | 6 | if [ "${X_ENABLED}" = "YES" ]; then 7 | xhost +"${jname}.${DOMAIN}" >/dev/null 2>&1 8 | fi 9 | -------------------------------------------------------------------------------- /cbsd-profile/system/facts.d/reggae_ip: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | MAC=`sqlite3 "${workdir}/jails-system/${jname}/local.sqlite" 'select nic_hwaddr from jailnic;'` 4 | cbsd jexec jname=cbsd "ip-by-mac.sh ${MAC}" 5 | -------------------------------------------------------------------------------- /templates/Makefile.project: -------------------------------------------------------------------------------- 1 | REGGAE_PATH = /usr/local/share/reggae 2 | # USE = letsencrypt nginx 3 | # SERVICES += myservice https://github.com/my/service 4 | 5 | .include <${REGGAE_PATH}/mk/project.mk> 6 | -------------------------------------------------------------------------------- /templates/devfs.rules: -------------------------------------------------------------------------------- 1 | [vnet=8] 2 | add include $devfsrules_hide_all 3 | add include $devfsrules_unhide_basic 4 | add include $devfsrules_unhide_login 5 | add path 'bpf*' unhide 6 | add path 'pf*' unhide 7 | -------------------------------------------------------------------------------- /skel/ansible/templates/site.yml.tpl: -------------------------------------------------------------------------------- 1 | # -*- mode: ansible -*- 2 | # vi: set ft=ansible : 3 | 4 | --- 5 | - name: SERVICE provisioning 6 | hosts: SERVICE 7 | roles: 8 | - onelove-roles.freebsd-common 9 | -------------------------------------------------------------------------------- /scripts/bhyve-init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | TEMPFILE=$(mktemp) 6 | 7 | reggae init ${@} 8 | echo "TYPE = bhyve" >"${TEMPFILE}" 9 | cat Makefile >>"${TEMPFILE}" 10 | mv "${TEMPFILE}" Makefile 11 | -------------------------------------------------------------------------------- /cbsd-profile/skel/usr/home/provision/.login_conf: -------------------------------------------------------------------------------- 1 | # $FreeBSD: releng/11.1/share/skel/dot.login_conf 77995 2001-06-10 17:08:53Z ache $ 2 | # 3 | # see login.conf(5) 4 | # 5 | #me:\ 6 | # :charset=iso-8859-1:\ 7 | # :lang=de_DE.ISO8859-1: 8 | -------------------------------------------------------------------------------- /templates/gitignore: -------------------------------------------------------------------------------- 1 | .provisioned 2 | ansible/group_vars/all 3 | ansible/inventory/inventory 4 | ansible/roles/* 5 | ansible/site.yml 6 | !ansible/roles/.keep 7 | build/ 8 | cbsd.conf 9 | site.retry 10 | project.mk 11 | vars.mk 12 | -------------------------------------------------------------------------------- /templates/resolvconf.conf: -------------------------------------------------------------------------------- 1 | name_servers=127.0.0.1 2 | resolv_conf_local_only=YES 3 | unbound_conf="/var/unbound/forward.conf" 4 | unbound_pid="/var/run/local_unbound.pid" 5 | unbound_service="local_unbound" 6 | unbound_restart="service local_unbound reload" 7 | -------------------------------------------------------------------------------- /templates/unbound_reggae.conf: -------------------------------------------------------------------------------- 1 | forward-zone: 2 | name: "DOMAIN" 3 | forward-addr: MASTER_IP 4 | 5 | forward-zone: 6 | name: "REVERSE" 7 | forward-addr: MASTER_IP 8 | 9 | forward-zone: 10 | name: "REVERSEV6" 11 | forward-addr: IPV6_PREFIXMASTER_IP6 12 | -------------------------------------------------------------------------------- /doc/base/README.md: -------------------------------------------------------------------------------- 1 | # Base integration 2 | 3 | Reggae configures `/etc/jail.conf` and the storage (ZFS dataset or directory on UFS). The idea is to use all the base FreeBSD can provide to run and manage jails. PF and network jail are configured like with CBSD backend. 4 | -------------------------------------------------------------------------------- /scripts/backend-init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ -f "/usr/local/etc/reggae.conf" ]; then 6 | . "/usr/local/etc/reggae.conf" 7 | fi 8 | 9 | SCRIPT_DIR=$(dirname $0) 10 | . "${SCRIPT_DIR}/default.conf" 11 | 12 | "${SCRIPT_DIR}/${BACKEND}-init.sh" 13 | -------------------------------------------------------------------------------- /scripts/get-config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | SCRIPT_DIR=$(dirname $0) 4 | . "${SCRIPT_DIR}/default.conf" 5 | 6 | if [ -f "/usr/local/etc/reggae.conf" ]; then 7 | . "/usr/local/etc/reggae.conf" 8 | fi 9 | 10 | raw_variable=$(echo "$"$1) 11 | variable=$(eval "echo" $raw_variable) 12 | echo $variable 13 | -------------------------------------------------------------------------------- /mk/chef.mk: -------------------------------------------------------------------------------- 1 | .include <${REGGAE_PATH}/mk/common.mk> 2 | 3 | PROVISIONERS += chef 4 | 5 | provision-chef: 6 | @mdo ${REGGAE_PATH}/scripts/chef-provision.sh ${SERVICE} ${TYPE} 7 | 8 | clean-chef: 9 | 10 | setup-chef: 11 | .if target(post_setup_chef) 12 | @${MAKE} ${MAKEFLAGS} post_setup_chef 13 | .endif 14 | -------------------------------------------------------------------------------- /mk/salt.mk: -------------------------------------------------------------------------------- 1 | .include <${REGGAE_PATH}/mk/common.mk> 2 | 3 | PROVISIONERS += salt 4 | 5 | provision-salt: 6 | @mdo ${REGGAE_PATH}/scripts/salt-provision.sh ${SERVICE} ${TYPE} 7 | 8 | clean-salt: 9 | 10 | setup-salt: 11 | .if target(post_setup_salt) 12 | @${MAKE} ${MAKEFLAGS} post_setup_salt 13 | .endif 14 | -------------------------------------------------------------------------------- /mk/shell.mk: -------------------------------------------------------------------------------- 1 | .include <${REGGAE_PATH}/mk/common.mk> 2 | 3 | PROVISIONERS += shell 4 | 5 | provision-shell: 6 | @mdo ${REGGAE_PATH}/scripts/shell-provision.sh ${SERVICE} ${TYPE} 7 | 8 | clean-shell: 9 | 10 | setup-shell: 11 | .if target(post_setup_shell) 12 | @${MAKE} ${MAKEFLAGS} post_setup_shell 13 | .endif 14 | -------------------------------------------------------------------------------- /cbsd-profile/skel/usr/home/provision/.login: -------------------------------------------------------------------------------- 1 | # $FreeBSD: releng/11.1/share/skel/dot.login 278616 2015-02-12 05:35:00Z cperciva $ 2 | # 3 | # .login - csh login script, read by login shell, after `.cshrc' at login. 4 | # 5 | # see also csh(1), environ(7). 6 | # 7 | 8 | if ( -x /usr/bin/fortune ) /usr/bin/fortune freebsd-tips 9 | -------------------------------------------------------------------------------- /templates/ip-by-mac.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ -z "$1" ]; then 4 | echo "Usage: $0 mac-address" >&2 5 | exit 1 6 | fi 7 | 8 | ( 9 | echo server MASTER_IP 10 | echo connect 11 | echo new lease 12 | echo set hardware-address = $1 13 | echo open 14 | ) | omshell | grep '^clientIP =' | cut -f 2 -d '"' 15 | 16 | -------------------------------------------------------------------------------- /mk/puppet.mk: -------------------------------------------------------------------------------- 1 | .include <${REGGAE_PATH}/mk/common.mk> 2 | 3 | PROVISIONERS += puppet 4 | 5 | provision-puppet: 6 | @mdo ${REGGAE_PATH}/scripts/puppet-provision.sh ${SERVICE} ${TYPE} 7 | 8 | clean-puppet: 9 | 10 | setup-puppet: 11 | .if target(post_setup_puppet) 12 | @${MAKE} ${MAKEFLAGS} post_setup_puppet 13 | .endif 14 | -------------------------------------------------------------------------------- /templates/setup-vm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | trap "rm -rf ${0}" HUP INT ABRT BUS TERM EXIT 4 | 5 | mdo sysrc hostname=SERVICE.DOMAIN 6 | mdo hostname SERVICE.DOMAIN 7 | mdo pw group add devel -g GID 8 | mdo pw user add devel -w none -m -s /bin/tcsh -u UID -G wheel 9 | mdo cp -rp ~provision/.ssh ~devel/ 10 | mdo chown -R devel:devel ~devel/ 11 | -------------------------------------------------------------------------------- /scripts/pf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | DIRECTORY=$1 5 | if [ -z "${DIRECTORY}" ]; then 6 | echo "Usage: reggae pf " >&2 7 | exit 1 8 | fi 9 | 10 | cd "${DIRECTORY}" 11 | for anchor_file in $(find . -type f); do 12 | anchor=$(echo ${anchor_file} | cut -b 3- | sed s/\.conf$//) 13 | pfctl -a ${anchor} -f ${anchor_file} 14 | done 15 | -------------------------------------------------------------------------------- /cbsd-profile/skel/usr/home/provision/.rhosts: -------------------------------------------------------------------------------- 1 | # $FreeBSD: releng/11.1/share/skel/dot.rhosts 50476 1999-08-28 00:22:10Z peter $ 2 | # 3 | # .rhosts - trusted remote host name and user data base 4 | # 5 | # see hosts.equiv(5), rsh(1), rlogin(1), rcp(1) 6 | # 7 | # This file should NOT be group or other readable. 8 | # OtherMachine 9 | # OtherMachine myFriend 10 | -------------------------------------------------------------------------------- /id_rsa.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD1rC034OUhsG+EzB9U7hEGOFVGqDMLZuXCNcT/I+Q2IUWPZzLjTTv8DjQ7DsUNdKBysNOdHK0WW/H25xcugxqFMNagUuJKiJm3tHof94+Y2xhwtDrTRtKgKGWOjxFggF6CyX2x6FfOaTF7bnYzjW1aDs5waTPLZBBmhJstS1+AArXA3yJUWeHntxpYK8eFj0lk/wOQJ5KCyihcjAfV+1Vm8IiFKMIsT/KjCw/9jS8H6rz1Yg89XBQljj67mPMRwVxAYAhHqGJpZY7+UuX3udELI1+pNup9R7EtF9WKYCVJMxpdcMU67SNuZWw5O548CUxzzM17sM7MRZdXlQIAspE7 reggae 2 | -------------------------------------------------------------------------------- /mk/common.mk: -------------------------------------------------------------------------------- 1 | TYPE ?= jail 2 | VERSION ?= native 3 | EXTRA_FSTAB ?= templates/fstab 4 | XORG ?= NO 5 | DEVEL_MODE ?= NO 6 | RUNNING_UID != id -u 7 | RUNNING_GID != id -g 8 | UID ?= ${RUNNING_UID} 9 | GID ?= ${RUNNING_GID} 10 | DOMAIN != reggae get-config DOMAIN 11 | EXTRA_PACKAGES = 12 | 13 | .for provisioner in ${PROVISIONERS} 14 | .if ${provisioner} == "ansible" 15 | EXTRA_PACKAGES += python 16 | .endif 17 | .endfor 18 | -------------------------------------------------------------------------------- /templates/freebsd-update.conf: -------------------------------------------------------------------------------- 1 | KeyPrint 800651ef4b4c71c27e60786d7b487188970f4b4169cc055784e21eb71d410cc5 2 | ServerName update.FreeBSD.org 3 | Components world 4 | IgnorePaths 5 | IDSIgnorePaths /usr/share/man/cat 6 | IDSIgnorePaths /usr/share/man/whatis 7 | IDSIgnorePaths /var/db/locate.database 8 | IDSIgnorePaths /var/log 9 | UpdateIfUnmodified /etc/ /var/ /root/ /.cshrc /.profile 10 | MergeChanges /etc/ /boot/device.hints 11 | -------------------------------------------------------------------------------- /templates/cloud-initial.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | pw group add provision -g 666 4 | pw user add provision -u 666 -g provision -s /bin/tcsh -G wheel -m 5 | sysrc ifconfig_vtnet0="SYNCDHCP" 6 | service cloudinit disable 7 | service nfsclient enable 8 | mkdir -p /home/provision/.ssh 9 | chmod 700 /home/provision/.ssh 10 | chpass -p '$6$61V0w0dRFFiEcnm2$o8CLPIdRBVHP13LQizdp12NEGD91RfHSB.c6uKnr9m2m3ZCg7ASeGENMaDt0tffmo5RalKGjWiHCtScCtjYfs/' provision 11 | -------------------------------------------------------------------------------- /cbsd-profile/skel/usr/home/provision/.mailrc: -------------------------------------------------------------------------------- 1 | # $FreeBSD: releng/11.1/share/skel/dot.mailrc 50476 1999-08-28 00:22:10Z peter $ 2 | # 3 | # .mailrc - mail resources 4 | # 5 | # see also mail(1) 6 | # 7 | 8 | set append ask autoprint 9 | set indentprefix="> " 10 | set PAGER=more 11 | set EDITOR=vi 12 | set VISUAL=vi 13 | set folder=Mail 14 | retain bcc cc date from subject to 15 | 16 | # include your private mail aliases 17 | source ~/.mail_aliases 18 | -------------------------------------------------------------------------------- /scripts/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | help() { 6 | echo "Usage: ${0} " 7 | } 8 | 9 | 10 | SCRIPT_DIR=$(dirname $0) 11 | . "${SCRIPT_DIR}/utils.sh" 12 | 13 | 14 | JNAME="${1}" 15 | if [ -z "${JNAME}" ]; then 16 | help >&2 17 | exit 1 18 | fi 19 | 20 | BACKEND=$(get_backend) 21 | 22 | 23 | if [ "${BACKEND}" = "base" ]; then 24 | service jail start "${JNAME}" 25 | elif [ "${BACKEND}" = "cbsd" ]; then 26 | cbsd jstart "${JNAME}" 27 | fi 28 | -------------------------------------------------------------------------------- /scripts/stop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | 6 | help() { 7 | echo "Usage: ${0} " 8 | } 9 | 10 | 11 | SCRIPT_DIR=$(dirname $0) 12 | . "${SCRIPT_DIR}/utils.sh" 13 | 14 | JNAME="${1}" 15 | if [ -z "${JNAME}" ]; then 16 | help >&2 17 | exit 1 18 | fi 19 | 20 | BACKEND=$(get_backend) 21 | 22 | 23 | if [ "${BACKEND}" = "base" ]; then 24 | service jail stop "${JNAME}" 25 | elif [ "${BACKEND}" = "cbsd" ]; then 26 | cbsd jstop "${JNAME}" 27 | fi 28 | -------------------------------------------------------------------------------- /cbsd-profile/skel/usr/home/provision/.mail_aliases: -------------------------------------------------------------------------------- 1 | # $FreeBSD: releng/11.1/share/skel/dot.mail_aliases 120555 2003-09-28 16:17:30Z rwatson $ 2 | # 3 | # .mail_aliases - private mail aliases 4 | # 5 | # see also mail(1) 6 | # 7 | 8 | # FreeBSD Mailing lists aliases 9 | # alias freebsd-bugs freebsd-bugs@FreeBSD.org 10 | # alias freebsd-questions freebsd-questions@FreeBSD.org 11 | 12 | # an alias for your good friends 13 | # alias bicycle christoph gerhardt velophil zentralrad 14 | -------------------------------------------------------------------------------- /scripts/export.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | set -e 5 | 6 | SERVICE="${1}" 7 | DESTINATION="${2}" 8 | if [ -z "${SERVICE}" -o -z "${DESTINATION}" ]; then 9 | echo "Usage: $0 " >&2 10 | exit 1 11 | fi 12 | 13 | BASE_WORKDIR="$(reggae get-config BASE_WORKDIR)" 14 | JAIL_PATH="${BASE_WORKDIR}/${SERVICE}" 15 | 16 | 17 | tar --zstd -c -p -f "${DESTINATION}/${SERVICE}.img" \ 18 | --cd "${JAIL_PATH}" \ 19 | . \ 20 | "/etc/jail.conf.d/${SERVICE}.conf" 21 | -------------------------------------------------------------------------------- /scripts/expect-run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | TEMP_FILE=$(mktemp) 4 | 5 | passwd_file=$1 6 | shift 7 | prompt_string=$1 8 | shift 9 | passwd=$(cat ${passwd_file}) 10 | 11 | echo "#!/usr/local/bin/expect -f" >"${TEMP_FILE}" 12 | echo "spawn $@" >>"${TEMP_FILE}" 13 | echo "expect ${prompt_string}" >>"${TEMP_FILE}" 14 | echo "send -- \"${passwd}\\r\"" >>"${TEMP_FILE}" 15 | echo "expect eof" >>"${TEMP_FILE}" 16 | chmod +x "${TEMP_FILE}" 17 | "${TEMP_FILE}" 18 | 19 | rm -rf "${TEMP_FILE}" 20 | -------------------------------------------------------------------------------- /templates/export-ports.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | EXPORTED_PORTS="" 5 | DOMAIN=`reggae get-config DOMAIN` 6 | 7 | for port in PRTS; do 8 | if [ -z "${EXPORTED_PORTS}" ]; then 9 | EXPORTED_PORTS="${port}" 10 | else 11 | EXPORTED_PORTS="${EXPORTED_PORTS}, ${port}" 12 | fi 13 | done 14 | 15 | 16 | if [ ! -z "${EXPORTED_PORTS}" ]; then 17 | echo "rdr pass inet proto { tcp, udp } from any to any port { ${EXPORTED_PORTS} } -> ${jname}.${DOMAIN}" | pfctl -a "cbsd/${jname}" -f - 18 | fi 19 | -------------------------------------------------------------------------------- /doc/provisioners/README.md: -------------------------------------------------------------------------------- 1 | # Reggae Provisioners 2 | 3 | Reggae supports following provisioners: 4 | * [ansible](ansible.md) 5 | * [chef](chef.md) 6 | * [puppet](puppet.md) 7 | * [salt](salt.md) 8 | * [shell](shell.md) 9 | 10 | To create a service with minimal provisioner skeleton, only slight modification in initialization is needed: 11 | ``` 12 | mkdir myservice 13 | cd myservice 14 | reggae init 15 | ``` 16 | Reggae will generate `playbook` directory where all files for your provisioner will be. 17 | -------------------------------------------------------------------------------- /scripts/base-init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ -f "/usr/local/etc/reggae.conf" ]; then 6 | . "/usr/local/etc/reggae.conf" 7 | fi 8 | 9 | SCRIPT_DIR=$(dirname $0) 10 | . "${SCRIPT_DIR}/default.conf" 11 | 12 | setup_base() { 13 | if [ ! -d /var/log/jails ]; then 14 | mkdir /var/log/jails 15 | fi 16 | touch /etc/jail.conf 17 | echo "reggae_enable=\"YES\"" >/etc/rc.conf.d/reggae 18 | service reggae start 19 | echo "jail_enable=\"YES\"" >/etc/rc.conf.d/jail 20 | echo "jail_list=\"\"" >>/etc/rc.conf.d/jail 21 | } 22 | 23 | 24 | setup_base 25 | -------------------------------------------------------------------------------- /scripts/get-ip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | SERVICE="${1}" 4 | 5 | 6 | help() { 7 | echo "Usage: $0 " 8 | } 9 | 10 | 11 | get_ip() { 12 | bhyve_conf="/usr/cbsd/jails-system/${SERVICE}/bhyve.conf" 13 | . "${bhyve_conf}" 14 | HWADDR=$(echo $nic_args | grep --color=auto -o 'mac=..:..:..:..:..:..' | cut -f 2 -d '=') 15 | IP="" 16 | while [ -z ${IP} ]; do 17 | IP=$(cbsd jexec jname=network cmd="ip-by-mac.sh ${HWADDR}") 18 | done 19 | echo ${IP} 20 | } 21 | 22 | 23 | if [ -z "${SERVICE}" ]; then 24 | help >&2 25 | exit 1 26 | fi 27 | 28 | 29 | get_ip 30 | -------------------------------------------------------------------------------- /doc/provisioners/shell.md: -------------------------------------------------------------------------------- 1 | # Shell Provisioner 2 | 3 | To get started, create directory named `myservice` and inside it run `reggae init shell`. It will be populated with the basic script so you can start writing more complex ones. Let's see what's inside: 4 | * Makefile - configured for use with Chef provisioner 5 | * playbook/cookbooks/core/recipes/default.rb - containing dummy provision.sh to start with 6 | 7 | When ran with this configuration, `reggae` will first mount playbook directory on `/root/shell` inside jail. To do actual provisioning, Reggae will run `/root/shell/provision.sh`. 8 | -------------------------------------------------------------------------------- /scripts/rmjail.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | NAME="${1}" 6 | if [ -z "${NAME}" ]; then 7 | echo "Usage: $0 " >&2 8 | exit 1 9 | fi 10 | BASE=$(reggae get-config BASE_WORKDIR) 11 | POOL=$(reggae get-config ZFS_POOL) 12 | USE_ZFS=$(reggae get-config USE_ZFS) 13 | 14 | 15 | service jail stop "${NAME}" 16 | sysrc -s jail jail_list-="${NAME}" 17 | if [ -e "${BASE}/${NAME}" ]; then 18 | if [ "${USE_ZFS}" = "yes" ]; then 19 | zfs destroy -f "${POOL}${BASE}/${NAME}" 20 | else 21 | rm -rf "${BASE}/${NAME}" 22 | fi 23 | fi 24 | rm -f "/etc/jail.conf.d/${NAME}.conf" 25 | -------------------------------------------------------------------------------- /mk/service.mk: -------------------------------------------------------------------------------- 1 | .if exists(vars.mk) 2 | .include 3 | .endif 4 | 5 | .if exists(project.mk) 6 | .include 7 | .endif 8 | 9 | .if exists(provisioners.mk) 10 | .include 11 | .endif 12 | 13 | USE_FREENIT ?= NO 14 | 15 | .if ${USE_FREENIT} == "YES" 16 | .include <${REGGAE_PATH}/mk/frameworks/freenit.service.mk> 17 | .endif 18 | 19 | .include <${REGGAE_PATH}/mk/common.mk> 20 | 21 | .MAIN: up 22 | 23 | update: 24 | @git pull 25 | @git submodule update --init --recursive 26 | 27 | restart: down up 28 | 29 | .include <${REGGAE_PATH}/mk/${TYPE}-service.mk> 30 | -------------------------------------------------------------------------------- /mk/frameworks/freenit.service.mk: -------------------------------------------------------------------------------- 1 | .if !target(shell) 2 | shell: up 3 | @mdo reggae jexec -U devel ${SERVICE} /usr/src/bin/shell.sh 4 | .endif 5 | 6 | do_devel: 7 | @mdo reggae jexec -U devel ${SERVICE} env OFFLINE=${offline} SYSPKG=${SYSPKG} BACKEND_URL=${BACKEND_URL} /usr/src/bin/devel.sh 8 | 9 | .if !target(collect) 10 | collect: 11 | @rm -rf build 12 | @mkdir -p build 13 | @mdo reggae jexec -U devel ${SERVICE} env OFFLINE=${offline} SYSPKG=${SYSPKG} /usr/src/bin/collect.sh 14 | .endif 15 | 16 | build_lib: up 17 | @mdo reggae jexec -U devel ${SERVICE} env OFFLINE=${offline} SYSPKG=${SYSPKG} /usr/src/bin/build.sh 18 | -------------------------------------------------------------------------------- /cbsd-profile/skel/etc/group: -------------------------------------------------------------------------------- 1 | # $FreeBSD: head/etc/group 256365 2013-10-12 06:06:53Z rpaulo $ 2 | # 3 | wheel:*:0:root,provision 4 | daemon:*:1: 5 | kmem:*:2: 6 | sys:*:3: 7 | tty:*:4: 8 | operator:*:5:root 9 | mail:*:6: 10 | bin:*:7: 11 | news:*:8: 12 | man:*:9: 13 | games:*:13: 14 | ftp:*:14: 15 | staff:*:20: 16 | sshd:*:22: 17 | smmsp:*:25: 18 | mailnull:*:26: 19 | guest:*:31: 20 | bind:*:53: 21 | unbound:*:59: 22 | proxy:*:62: 23 | authpf:*:63: 24 | _pflogd:*:64: 25 | _dhcp:*:65: 26 | uucp:*:66: 27 | dialer:*:68: 28 | network:*:69: 29 | audit:*:77: 30 | www:*:80: 31 | hast:*:845: 32 | nogroup:*:65533: 33 | nobody:*:65534: 34 | provision:*:666: 35 | -------------------------------------------------------------------------------- /templates/unbound.conf: -------------------------------------------------------------------------------- 1 | server: 2 | verbosity: 1 3 | username: unbound 4 | directory: /var/unbound 5 | chroot: /var/unbound 6 | pidfile: /var/run/local_unbound.pid 7 | auto-trust-anchor-file: /var/unbound/root.key 8 | root-hints: /var/unbound/root.hints 9 | interface: 127.0.0.1 10 | interface: INTERFACE_IP 11 | interface: IPV6_PREFIXINTERFACE_IP6 12 | access-control: 0.0.0.0/0 allow_snoop 13 | val-permissive-mode: yes 14 | 15 | include: /var/unbound/reggae.conf 16 | include: /var/unbound/control.conf 17 | include: /var/unbound/forward.conf 18 | include: /var/unbound/lan-zones.conf 19 | include: /var/unbound/conf.d/*.conf 20 | -------------------------------------------------------------------------------- /doc/provisioners/puppet.md: -------------------------------------------------------------------------------- 1 | # Puppet Provisioner 2 | 3 | To get started, create directory named `myservice` and inside it run `reggae init puppet`. It will be populated with the basic role so you can start writing more complex ones. Let's see what's inside: 4 | * Makefile - configured for use with Puppet 5 | * playbook/site.pp - dummy role to start with 6 | 7 | When ran with this configuration, `reggae` will first check if `puppet` executable is available inside jail, and if it isn't, it will install it from packages. Then it will mount `playbook` directory on `/usr/local/etc/puppet/manifests` inside jail. To do actual provisioning, Reggae uses `puppet apply`. 8 | -------------------------------------------------------------------------------- /scripts/ssh.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | SCRIPT_DIR=$(dirname $0) 6 | PROJECT_ROOT=$(readlink -f ${SCRIPT_DIR}/..) 7 | USER="${1}" 8 | SERVICE="${2}" 9 | shift 10 | shift 11 | IP=${IP:=$(reggae get-ip ${SERVICE})} 12 | 13 | 14 | help() { 15 | echo "Usage: $0 " 16 | } 17 | 18 | 19 | if [ -z "${USER}" -o -z "${SERVICE}" ]; then 20 | help >&2 21 | exit 1 22 | fi 23 | 24 | ssh_cmd="ssh -t -i ${PROJECT_ROOT}/id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${USER}@${IP} ${@}" 25 | 26 | if [ "${VERBOSE}" = "yes" ]; then 27 | echo "ssh_cmd=${ssh_cmd}" 28 | ${ssh_cmd} 29 | else 30 | ${ssh_cmd} >/dev/null 2>&1 31 | fi 32 | -------------------------------------------------------------------------------- /doc/provisioners/chef.md: -------------------------------------------------------------------------------- 1 | # Chef Provisioner 2 | 3 | To get started, create directory named `myservice` and inside it run `reggae init chef`. It will be populated with the basic script so you can start writing more complex ones. Let's see what's inside: 4 | * Makefile - configured for use with Shell provisioner 5 | * playbook - containing `cookbooks/core/recipes/default.rb` dummy script 6 | 7 | When ran with this configuration, `reggae` will first check if `chef-client` executable is available inside jail, and if it isn't, it will install it from packages. Then it will mount playbook directory on `/root/chef` inside jail. To do actual provisioning, Reggae uses `chef-client --local-mode`. 8 | -------------------------------------------------------------------------------- /templates/pf-jail.conf: -------------------------------------------------------------------------------- 1 | # Macros and tables 2 | ext_if = "eth0" 3 | 4 | # Options 5 | set block-policy drop 6 | set skip on lo0 7 | 8 | # Normalization 9 | scrub in all 10 | 11 | # Redirect 12 | rdr-anchor "rdr-services" 13 | load anchor "rdr-services" from "/etc/pf.services" 14 | 15 | # Rules 16 | block in log from any to (self) 17 | pass in inet proto udp to any port bootpc 18 | pass in inet6 proto udp from fe80::/10 port dhcpv6-server to fe80::/10 port dhcpv6-client 19 | pass in proto tcp to any port ssh 20 | pass in proto { icmp, igmp, icmp6 } 21 | pass in from ($ext_if:network) 22 | pass out 23 | 24 | anchor "services" 25 | load anchor "services" from "/etc/pf.services" 26 | -------------------------------------------------------------------------------- /doc/provisioners/salt.md: -------------------------------------------------------------------------------- 1 | # Salt Provisioner 2 | 3 | To get started, create directory named `myservice` and inside it run `reggae init salt`. It will be populated with the basic script so you can start writing more complex ones. Let's see what's inside: 4 | * Makefile - configured for use with Shell provisioner 5 | * playbook - containing `top.sls` and `core.sls` playbooks 6 | 7 | When ran with this configuration, `reggae` will first check if `salt` executable is available inside jail, and if it isn't, it will run `pkg install -y py36-salt` inside jail. Then it will mount playbook directory on `/usr/local/etc/salt/states` inside jail. To do actual provisioning, Reggae uses `salt-call --local state.apply`. 8 | -------------------------------------------------------------------------------- /reggae.conf.sample: -------------------------------------------------------------------------------- 1 | # Commented are default values 2 | 3 | # BACKEND="base" 4 | # CBSD_WORKDIR="/usr/cbsd" 5 | # BASE_WORKDIR="/var/jails" 6 | # MASTER_IP="172.16.0.253" 7 | # MASTER_IP6=":2" 8 | # DOMAIN=`hostname` 9 | # INTERFACE="jails" 10 | # INTERFACE_IP="172.16.0.254" 11 | # INTERFACE_IP6=":1" 12 | # JAIL_INTERFACE_IP="172.16.1.254" 13 | # ZFS_POOL="zroot" 14 | # PROJECTS_DIR="/home/user/reggae/repos" 15 | # PKG_MIRROR="pkg.FreeBSD.org" 16 | # PKG_REPO="latest" 17 | # PKG_PROXY="no" 18 | # IPV6_PREFIX="fd10:6c79:8ae5:8b91:" 19 | # USE_ZFS="yes" 20 | # USE_IPV4="yes" 21 | # USE_IPV6="yes" 22 | # BRIDGE_MEMBERS="" 23 | # DHCP="dhcpcd" # can be 'dhcpcd' or 'dhclient' 24 | # DNS_OVERRIDE="" # space separated list of IP addresses 25 | -------------------------------------------------------------------------------- /bin/reggae: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | SCRIPT_ROOT="${SCRIPT_ROOT:=/usr/local/share/reggae/scripts}" 4 | 5 | help() { 6 | echo "Usage: $0 " 7 | echo "where action is one of:" 8 | cd "${SCRIPT_ROOT}" 9 | for script_file in $(find . -name '*.sh' -perm 755 | cut -f 2 -d '/' | sort); do 10 | if [ -x "${script_file}" ]; then 11 | echo -n " " 12 | echo "${script_file}" | sed 's/\.sh$//' 13 | fi 14 | done 15 | } 16 | 17 | case "${1}" in 18 | --version) 19 | shift 20 | "${SCRIPT_ROOT}/version.sh" 21 | break 22 | ;; 23 | *) 24 | SCRIPT="${SCRIPT_ROOT}/${1}.sh" 25 | if [ ! -x "${SCRIPT}" ]; then 26 | help >&2 27 | exit 1 28 | fi 29 | shift 30 | "${SCRIPT}" ${@} 31 | ;; 32 | esac 33 | 34 | -------------------------------------------------------------------------------- /scripts/scp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ -f "/usr/local/etc/reggae.conf" ]; then 6 | . "/usr/local/etc/reggae.conf" 7 | fi 8 | 9 | SCRIPT_DIR=$(dirname $0) 10 | PROJECT_ROOT=$(readlink -f ${SCRIPT_DIR}/..) 11 | USER="${1}" 12 | SERVICE="${2}" 13 | FILE="${3}" 14 | VERBOSE=${VERBOSE:="no"} 15 | IP=${IP:=$(reggae get-ip ${SERVICE})} 16 | 17 | help() { 18 | echo "Usage: $0 " 19 | } 20 | 21 | 22 | if [ -z "${USER}" -o -z "${SERVICE}" -o -z "${FILE}" ]; then 23 | help >&2 24 | exit 1 25 | fi 26 | 27 | scp_cmd="scp -r -i ${PROJECT_ROOT}/id_rsa -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${FILE} ${USER}@${IP}:" 28 | if [ "${VERBOSE}" = "yes" ]; then 29 | ${scp_cmd} 30 | else 31 | ${scp_cmd} >/dev/null 2>&1 32 | fi 33 | -------------------------------------------------------------------------------- /scripts/ssh-ping.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | SCRIPT_DIR=$(dirname $0) 6 | PROJECT_ROOT=$(readlink -f ${SCRIPT_DIR}/..) 7 | SERVICE="${1}" 8 | shift 9 | COMMAND="${@}" 10 | COMMAND="${COMMAND:=true}" 11 | SSH_USER=${SSH_USER:=provision} 12 | 13 | help() { 14 | echo "Usage: $0 " 15 | } 16 | 17 | 18 | wait_ssh() { 19 | if [ -z "${1}" ]; then 20 | echo "Usage: $0 " >&2 21 | exit 1 22 | fi 23 | EXIT_STATUS=1 24 | while [ "${EXIT_STATUS}" != "0" ]; do 25 | reggae ssh ${SSH_USER} ${1} "${COMMAND}" 26 | EXIT_STATUS=$? 27 | if [ "${EXIT_STATUS}" != "0" ]; then 28 | sleep 1 29 | fi 30 | done 31 | } 32 | 33 | 34 | if [ -z "${SERVICE}" ]; then 35 | help >&2 36 | exit 1 37 | fi 38 | 39 | 40 | wait_ssh "${SERVICE}" 41 | -------------------------------------------------------------------------------- /scripts/default.conf: -------------------------------------------------------------------------------- 1 | VERSION=0.5.1 2 | 3 | BACKEND=${BACKEND:-"base"} 4 | CBSD_WORKDIR=${CBSD_WORKDIR:-"/usr/cbsd"} 5 | BASE_WORKDIR=${BASE_WORKDIR:-"/var/jails"} 6 | MASTER_IP=${MASTER_IP:-"172.16.0.253"} 7 | MASTER_IP6=${MASTER_IP6:-":2"} 8 | DOMAIN=${DOMAIN:-`hostname`} 9 | INTERFACE=${INTERFACE:-"jails"} 10 | INTERFACE_IP=${INTERFACE_IP:-"172.16.0.254"} 11 | INTERFACE_IP6=${INTERFACE_IP6:-":1"} 12 | JAIL_INTERFACE_IP=${JAIL_INTERFACE_IP:-"172.16.1.254"} 13 | ZFS_POOL=${ZFS_POOL:-"zroot"} 14 | PKG_MIRROR=${PKG_MIRROR:-"pkg.FreeBSD.org"} 15 | PKG_REPO=${PKG_REPO:-"latest"} 16 | PKG_PROXY=${PKG_PROXY:="no"} 17 | IPV6_PREFIX=${IPV6_PREFIX:="fd10:6c79:8ae5:8b91:"} 18 | USE_ZFS=${USE_ZFS:="yes"} 19 | USE_IPV4=${USE_IPV4:="yes"} 20 | USE_IPV6=${USE_IPV6:="yes"} 21 | DHCP=${DHCP:="dhcpcd"} 22 | -------------------------------------------------------------------------------- /templates/initenv.conf: -------------------------------------------------------------------------------- 1 | nodeip="NODEIP" 2 | jnameserver="INTERFACE_IP" 3 | nodeippool="JAIL_IP_POOL" 4 | nodeip6pool="JAIL_IP6_POOL" 5 | nat_enable="0" 6 | fbsdrepo="1" 7 | zfsfeat="ZFSFEAT" 8 | parallel="5" 9 | stable="0" 10 | sqlreplica="1" 11 | statsd_bhyve_enable="0" 12 | statsd_jail_enable="0" 13 | statsd_hoster_enable="0" 14 | ipfw_enable="0" 15 | nodename="HOSTNAME" 16 | racct="1" 17 | natip="" 18 | initenv_modify_sudoers="" 19 | initenv_modify_rcconf_hostname="" 20 | initenv_modify_rcconf_cbsd_workdir="1" 21 | initenv_modify_rcconf_cbsd_enable="1" 22 | initenv_modify_rcconf_rcshutdown_timeout="" 23 | initenv_modify_syctl_rcshutdown_timeout="" 24 | initenv_modify_rcconf_cbsdrsyncd_enable="1" 25 | initenv_modify_rcconf_cbsdrsyncd_flags="1" 26 | initenv_modify_cbsd_homedir="0" 27 | workdir="CBSD_WORKDIR" 28 | -------------------------------------------------------------------------------- /cbsd-profile/skel/etc/crontab: -------------------------------------------------------------------------------- 1 | # /etc/crontab - root's crontab for FreeBSD 2 | # 3 | # $FreeBSD: head/etc/crontab 194170 2009-06-14 06:37:19Z brian $ 4 | # 5 | SHELL=/bin/sh 6 | PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin 7 | # 8 | #minute hour mday month wday who command 9 | # 10 | */5 * * * * root /usr/libexec/atrun 11 | # 12 | # Save some entropy so that /dev/random can re-seed on boot. 13 | */11 * * * * operator /usr/libexec/save-entropy 14 | # 15 | # Rotate log files every hour, if necessary. 16 | 0 * * * * root newsyslog 17 | # 18 | # Perform daily/weekly/monthly maintenance. 19 | 1 3 * * * root periodic daily 20 | 15 4 * * 6 root periodic weekly 21 | 30 5 1 * * root periodic monthly 22 | # 23 | # Adjust the time zone if the CMOS clock keeps local time, as opposed to 24 | # UTC time. See adjkerntz(8) for details. 25 | 1,31 0-5 * * * root adjkerntz -a 26 | -------------------------------------------------------------------------------- /scripts/shell-provision.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | BACKEND=$(reggae get-config BACKEND) 6 | SERVICE="${1}" 7 | TYPE="${2}" 8 | JAIL_PATH=$(jls -j ${SERVICE} path) 9 | 10 | cleanup() { 11 | umount "${JAIL_PATH}/root/shell" 12 | } 13 | 14 | if [ -z "${SERVICE}" ]; then 15 | echo "Usage: ${0} " 2>&1 16 | exit 1 17 | fi 18 | 19 | trap "cleanup" HUP INT ABRT BUS TERM EXIT 20 | 21 | if [ "${TYPE}" = "jail" ]; then 22 | mkdir "${JAIL_PATH}/root/shell" >/dev/null 2>&1 || true 23 | mount_nullfs "${PWD}/shell" "${JAIL_PATH}/root/shell" 24 | reggae jexec ${SERVICE} /root/shell/provision.sh 25 | elif [ "${TYPE}" = "bhyve" ]; then 26 | reggae scp provision ${SERVICE} shell 27 | env VERBOSE="yes" reggae ssh provision ${SERVICE} mdo shell/provision.sh 28 | else 29 | echo "Type ${TYPE} unknown!" >&2 30 | exit 1 31 | fi 32 | -------------------------------------------------------------------------------- /scripts/jexec.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | help() { 6 | echo "Usage: ${0} [options] " 7 | echo "" 8 | echo "options:" 9 | echo " -U " 10 | echo " Jail user to execute command as." 11 | } 12 | 13 | 14 | SCRIPT_DIR=$(dirname $0) 15 | . "${SCRIPT_DIR}/utils.sh" 16 | 17 | JAIL_USER="root" 18 | optstring="U:" 19 | args=$(getopt "${optstring}" ${*}) 20 | if [ $? -ne 0 ]; then 21 | help >&2 22 | exit 1 23 | fi 24 | set -- ${args} 25 | while :; do 26 | case "${1}" in 27 | -U) 28 | JAIL_USER="${2}" 29 | shift; shift 30 | ;; 31 | --) 32 | shift 33 | break 34 | ;; 35 | esac 36 | done 37 | 38 | 39 | JNAME="${1}" 40 | shift 41 | COMMAND="${@}" 42 | if [ -z "${JNAME}" -o -z "${COMMAND}" ]; then 43 | help >&2 44 | exit 1 45 | fi 46 | 47 | 48 | execute_command "${JNAME}" "${COMMAND}" 49 | -------------------------------------------------------------------------------- /scripts/update-profiles.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ -f "/usr/local/etc/reggae.conf" ]; then 6 | . "/usr/local/etc/reggae.conf" 7 | fi 8 | 9 | SCRIPT_DIR=$(dirname $0) 10 | PROJECT_DIR="${SCRIPT_DIR}/.." 11 | . "${SCRIPT_DIR}/default.conf" 12 | 13 | RSYNC_CMD="rsync --recursive --verbose --progress --delete-after" 14 | 15 | 16 | echo ${RSYNC_CMD} ${PROJECT_DIR}/cbsd-profile/system/ ${CBSD_WORKDIR}/share/jail-system-reggae/ 17 | ${RSYNC_CMD} ${PROJECT_DIR}/cbsd-profile/system/ ${CBSD_WORKDIR}/share/jail-system-reggae/ 18 | echo ${RSYNC_CMD} ${PROJECT_DIR}/cbsd-profile/skel/ ${CBSD_WORKDIR}/share/FreeBSD-jail-reggae-skel/ 19 | ${RSYNC_CMD} ${PROJECT_DIR}/cbsd-profile/skel/ ${CBSD_WORKDIR}/share/FreeBSD-jail-reggae-skel/ 20 | echo cp ${PROJECT_DIR}/cbsd-profile/jail-freebsd-reggae.conf ${CBSD_WORKDIR}/etc/defaults/ 21 | cp ${PROJECT_DIR}/cbsd-profile/jail-freebsd-reggae.conf ${CBSD_WORKDIR}/etc/defaults/ 22 | -------------------------------------------------------------------------------- /cbsd-profile/jail-freebsd-reggae.conf: -------------------------------------------------------------------------------- 1 | # This is sample for trusted jail profile and alternative jail-skel dir 2 | jail_profile="reggae" 3 | 4 | # suggest for jail1, jail2 5 | default_jailname="jail" 6 | default_domain="DOMAIN" 7 | 8 | emulator="jail" 9 | 10 | jail_active="1" 11 | 12 | # this is one-string additional info strings in dialogue menu 13 | long_description="Reggae jails" 14 | 15 | # autostart asap upon jail created 16 | runasap="1" 17 | 18 | jailskeldir="${workdir}/share/${platform}-jail-reggae-skel" 19 | jailsysskeldir="${workdir}/share/jail-system-reggae" 20 | pkg_bootstrap="1" 21 | interface="JAIL_INTERFACE" 22 | mount_ports="0" 23 | 24 | user_add='provision' 25 | user_gecos_provision='provision' 26 | user_home_provision='/home/provision' 27 | user_shell_provision='/bin/tcsh' 28 | user_pw_provision_crypt='$6$txHZRMg6YhOKZjeB$VHJKERRf75JSrswKQUL.NvWG3Wm42seRGzTBRZ3dBe0QNOR1f9NoyPZ.2UGdjXbjR7p3gUk33xWoaGH1803Xq0' 29 | -------------------------------------------------------------------------------- /cbsd-profile/skel/usr/home/provision/.profile: -------------------------------------------------------------------------------- 1 | # $FreeBSD: releng/11.1/share/skel/dot.profile 278616 2015-02-12 05:35:00Z cperciva $ 2 | # 3 | # .profile - Bourne Shell startup script for login shells 4 | # 5 | # see also sh(1), environ(7). 6 | # 7 | 8 | # These are normally set through /etc/login.conf. You may override them here 9 | # if wanted. 10 | # PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:$HOME/bin; export PATH 11 | # BLOCKSIZE=K; export BLOCKSIZE 12 | 13 | # Setting TERM is normally done through /etc/ttys. Do only override 14 | # if you're sure that you'll never log in via telnet or xterm or a 15 | # serial line. 16 | # TERM=xterm; export TERM 17 | 18 | EDITOR=vi; export EDITOR 19 | PAGER=more; export PAGER 20 | 21 | # set ENV to a file invoked each time sh is started for interactive use. 22 | ENV=$HOME/.shrc; export ENV 23 | 24 | if [ -x /usr/bin/fortune ] ; then /usr/bin/fortune freebsd-tips ; fi 25 | -------------------------------------------------------------------------------- /templates/base-jail.conf: -------------------------------------------------------------------------------- 1 | $base = BASE_WORKDIR; 2 | persist; 3 | vnet; 4 | path = "${base}/${name}"; 5 | mount.devfs; 6 | host.domainname = "HOST"; 7 | host.hostname = "${name}.${host.domainname}"; 8 | $host_interface = "epair${id}a"; 9 | vnet.interface = "epair${id}b"; 10 | devfs_ruleset = 8; 11 | allow.raw_sockets; 12 | allow.chflags; 13 | 14 | exec.prepare = "ifconfig ${host_interface} destroy >/dev/null 2>&1 || true"; 15 | 16 | exec.prestart = "ifconfig epair${id} create group $(echo ${name} | cut -b 1-15) up >/dev/null 2>&1 || (ifconfig ${host_interface} destroy && false)"; 17 | exec.prestart += "ifconfig jails addm ${host_interface}"; 18 | 19 | exec.start = "ifconfig ${vnet.interface} name eth0"; 20 | exec.start += "/bin/sh /etc/rc"; 21 | 22 | exec.stop = "/bin/sh /etc/rc.shutdown jail"; 23 | 24 | exec.poststop = "ifconfig ${host_interface} destroy"; 25 | 26 | exec.clean; 27 | exec.consolelog = "/var/log/jails/${host.hostname}"; 28 | -------------------------------------------------------------------------------- /templates/pf.conf: -------------------------------------------------------------------------------- 1 | # Macros and tables 2 | ext_if = "EGRESS" 3 | jail_if = "INTERFACE" 4 | 5 | # Options 6 | set block-policy drop 7 | set skip on lo0 8 | 9 | # Normalization 10 | scrub in all 11 | 12 | # NAT (comment out if adding ext_if to bridge) 13 | nat on $ext_if inet from ($jail_if:network) to any -> ($ext_if) 14 | nat on $ext_if inet6 from ($jail_if:network) to any -> ($ext_if:0) 15 | 16 | # RDR anchors, mostly for port forwarding 17 | rdr-anchor "reggae/*" on $ext_if 18 | # rdr-anchor "service/*" on $ext_if 19 | 20 | antispoof quick log for ($ext_if) # comment out if adding ext_if to bridge 21 | anchor "blacklistd/*" in on $ext_if 22 | 23 | # Rules 24 | block in log from any to (self) 25 | pass in on $jail_if 26 | pass in inet proto udp to any port bootpc 27 | pass in inet6 proto udp from fe80::/10 port dhcpv6-server to fe80::/10 port dhcpv6-client 28 | pass in proto tcp to (self) port ssh 29 | pass in proto { icmp, igmp, icmp6 } 30 | pass out 31 | -------------------------------------------------------------------------------- /doc/provisioners/ansible.md: -------------------------------------------------------------------------------- 1 | # Ansible Provisioner 2 | 3 | To get started, create directory named `myservice` and inside it run `reggae init ansible`. It will be populated with the basic role so you can start writing more complex ones. Let's see what's inside: 4 | * Makefile - configured for use with Ansible 5 | * playbook - containing `group_vars`, `inventory` and `roles` directories as placeholders for files generated on the fly, but can be used to configure your playbook 6 | * requirements.yml - list of requirements, with only one initially. All requirements from this file are downloaded from [Ansible Galaxy](https://galaxy.ansible.com) 7 | * templates/site.yml.tpl - this file should be edited to add/remove roles, playbooks, etc. 8 | 9 | When ran with this configuration, `reggae` will first check if `ansible` executable is available, and if it isn't, it will run `pkg install ansible`. If you use Python's virtual environments, for example, you can avoid having `ansible` available to everyone on the system. 10 | -------------------------------------------------------------------------------- /templates/cloud-devops.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | SERVER="${1}" 5 | DIRECTORY="${2}" 6 | MOUNTPOINT="${3}" 7 | EXTRA_SCRIPT="${4}" 8 | 9 | if [ $# -lt 3 ]; then 10 | echo "${0} " >&2 11 | exit 1 12 | fi 13 | 14 | 15 | if [ ! -e /home/devel/.ssh/authorized_keys ]; then 16 | pw group add devel -g ${GID} 17 | pw user add devel -u ${UID} -g devel -s /bin/tcsh -G wheel -m 18 | mkdir -p /home/devel/.ssh 19 | chmod 700 /home/devel/.ssh 20 | chpass -p '$6$61V0w0dRFFiEcnm2$o8CLPIdRBVHP13LQizdp12NEGD91RfHSB.c6uKnr9m2m3ZCg7ASeGENMaDt0tffmo5RalKGjWiHCtScCtjYfs/' devel 21 | cp /home/provision/id_rsa.pub /home/devel/.ssh/authorized_keys 22 | chmod 600 /home/devel/.ssh/authorized_keys 23 | chown -R devel:devel /home/devel 24 | fi 25 | 26 | 27 | if [ ! -e "${MOUNTPOINT}/Makefile" ]; then 28 | mount "${SERVER}:${DIRECTORY}" "${MOUNTPOINT}" 29 | if [ ! -z "${EXTRA_SCRIPT}" ]; then 30 | EXTRA_SCRIPT_ABS="/usr/local/bin/`basename ${EXTRA_SCRIPT}`" 31 | sh "${EXTRA_SCRIPT_ABS}" 32 | fi 33 | fi 34 | -------------------------------------------------------------------------------- /cbsd-profile/skel/usr/home/provision/.shrc: -------------------------------------------------------------------------------- 1 | # $FreeBSD: releng/11.1/share/skel/dot.shrc 313286 2017-02-05 14:25:31Z jilles $ 2 | # 3 | # .shrc - bourne shell startup file 4 | # 5 | # This file will be used if the shell is invoked for interactive use and 6 | # the environment variable ENV is set to this file. 7 | # 8 | # see also sh(1), environ(7). 9 | # 10 | 11 | 12 | # file permissions: rwxr-xr-x 13 | # 14 | # umask 022 15 | 16 | # Uncomment this to enable the builtin vi(1) command line editor in sh(1), 17 | # e.g. ESC to go into visual mode. 18 | # set -o vi 19 | 20 | 21 | # some useful aliases 22 | alias h='fc -l' 23 | alias j=jobs 24 | alias m=$PAGER 25 | alias ll='ls -laFo' 26 | alias l='ls -l' 27 | alias g='egrep -i' 28 | 29 | # # be paranoid 30 | # alias cp='cp -ip' 31 | # alias mv='mv -i' 32 | # alias rm='rm -i' 33 | 34 | 35 | # # set prompt: ``username@hostname$ '' 36 | # PS1="`whoami`@`hostname | sed 's/\..*//'`" 37 | # case `id -u` in 38 | # 0) PS1="${PS1}# ";; 39 | # *) PS1="${PS1}$ ";; 40 | # esac 41 | 42 | # search path for cd(1) 43 | # CDPATH=:$HOME 44 | -------------------------------------------------------------------------------- /doc/README.md: -------------------------------------------------------------------------------- 1 | # Documentation 2 | 3 | To configure the host system, run `reggae host-init`. As it sets up PF, you 4 | should `service pf restart` before continuing. As restarting PF will cut off 5 | existing connections, Reggae will not do it on its own. 6 | 7 | Next, you need to initialize the backend. Currently there are two backends 8 | available: 9 | 10 | * base 11 | * cbsd 12 | 13 | By default Reggae will use `base` which means only FreeBSD base tools are used. 14 | To initialize base, run `reggae base-init` and to initialize CBSD run 15 | `reggae cbsd-init`. It is perfectly valid to initialize both, but using jails 16 | from different backends can be tricky. Usually, you will need only one backend. 17 | 18 | The last in line to configure is network jail with DHCP and DNS services. The 19 | command `reggae network-init` will do just that. You can configure backend 20 | through `/usr/local/etc/reggae.conf` or through environment variable like 21 | `env BACKEND=cbsd reggae network-init`. 22 | 23 | * [Base Integration](base) 24 | * [CBSD Integration](cbsd) 25 | * [Provisioners](provisioners) 26 | -------------------------------------------------------------------------------- /scripts/apply-proxy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | BACKEND=$(reggae get-config BACKEND) 6 | PKG_PROXY=$(reggae get-config PKG_PROXY) 7 | 8 | if [ "${BACKEND}" = "base" ]; then 9 | BASE_WORKDIR=$(reggae get-config BASE_WORKDIR) 10 | for jail_version in $(ls -1d "${BASE_WORKDIR}"/*/bin/freebsd-version); do 11 | jname=$(echo "${jail_version}" | sed "s;${BASE_WORKDIR}/;;g" | cut -f 1 -d '/') 12 | pkg_file="${BASE_WORKDIR}/${jname}/usr/local/etc/pkg.conf" 13 | sed -i "" -r "/^pkg_env.*/d" "${pkg_file}" 14 | if [ "${PKG_PROXY}" != "no" ]; then 15 | echo "pkg_env : { http_proxy: \"http://${PKG_PROXY}/\" }" >>"${pkg_file}" 16 | fi 17 | done 18 | elif [ "${BACKEND}" = "cbsd" ]; then 19 | CBSD_WORKDIR=$(sysrc -s cbsdd -n cbsd_workdir) 20 | for jname in $(env NOCOLOR=1 cbsd jls header=0 display=jname); do 21 | pkg_file="${CBSD_WORKDIR}/jails-data/${jname}-data/usr/local/etc/pkg.conf" 22 | sed -i "" -r "/^pkg_env.*/d" "${pkg_file}" 23 | if [ "${PKG_PROXY}" != "no" ]; then 24 | echo "pkg_env : { http_proxy: \"http://${PKG_PROXY}/\" }" >>"${pkg_file}" 25 | fi 26 | done 27 | fi 28 | -------------------------------------------------------------------------------- /cbsd-profile/skel/root/.cshrc: -------------------------------------------------------------------------------- 1 | # $FreeBSD: head/etc/root/dot.cshrc 243893 2012-12-05 13:56:39Z eadler $ 2 | # 3 | # .cshrc - csh resource script, read at beginning of execution by each shell 4 | # 5 | # see also csh(1), environ(7). 6 | # more examples available at /usr/share/examples/csh/ 7 | # 8 | 9 | alias h history 25 10 | alias j jobs -l 11 | alias la ls -aF 12 | alias lf ls -FA 13 | alias ll ls -lAF 14 | 15 | # A righteous umask 16 | umask 22 17 | 18 | set path = (/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin $HOME/bin) 19 | 20 | setenv EDITOR vi 21 | setenv PAGER more 22 | setenv BLOCKSIZE K 23 | 24 | if ($?prompt) then 25 | # An interactive shell -- set some stuff up 26 | # set prompt = "%N@%m:%~ %# " 27 | set prompt = "%{^[[40;35;1m%}`/bin/hostname -s`:%{^[[40;31;1m%}%/@%{^[[40;33;1m%}%B[%T]%b # " 28 | set promptchars = "%#" 29 | 30 | set filec 31 | set history = 1000 32 | set savehist = (1000 merge) 33 | set autolist = ambiguous 34 | # Use history to aid expansion 35 | set autoexpand 36 | set autorehash 37 | set mail = (/var/mail/$USER) 38 | if ( $?tcsh ) then 39 | bindkey "^W" backward-delete-word 40 | bindkey -k up history-search-backward 41 | bindkey -k down history-search-forward 42 | endif 43 | 44 | endif 45 | -------------------------------------------------------------------------------- /cbsd-profile/skel/usr/home/provision/.cshrc: -------------------------------------------------------------------------------- 1 | # $FreeBSD: releng/11.1/share/skel/dot.cshrc 278616 2015-02-12 05:35:00Z cperciva $ 2 | # 3 | # .cshrc - csh resource script, read at beginning of execution by each shell 4 | # 5 | # see also csh(1), environ(7). 6 | # more examples available at /usr/share/examples/csh/ 7 | # 8 | 9 | alias h history 25 10 | alias j jobs -l 11 | alias la ls -aF 12 | alias lf ls -FA 13 | alias ll ls -lAF 14 | 15 | # These are normally set through /etc/login.conf. You may override them here 16 | # if wanted. 17 | # set path = (/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin $HOME/bin) 18 | # setenv BLOCKSIZE K 19 | # A righteous umask 20 | # umask 22 21 | 22 | setenv EDITOR vi 23 | setenv PAGER more 24 | 25 | if ($?prompt) then 26 | # An interactive shell -- set some stuff up 27 | set prompt = "%N@%m:%~ %# " 28 | set promptchars = "%#" 29 | 30 | set filec 31 | set history = 1000 32 | set savehist = (1000 merge) 33 | set autolist = ambiguous 34 | # Use history to aid expansion 35 | set autoexpand 36 | set autorehash 37 | set mail = (/var/mail/$USER) 38 | if ( $?tcsh ) then 39 | bindkey "^W" backward-delete-word 40 | bindkey -k up history-search-backward 41 | bindkey -k down history-search-forward 42 | endif 43 | 44 | endif 45 | -------------------------------------------------------------------------------- /templates/dhcpd.conf: -------------------------------------------------------------------------------- 1 | server-identifier DOMAIN; 2 | authoritative; 3 | log-facility local7; 4 | omapi-port 7911; 5 | 6 | 7 | subnet DHCP_BASE.0 netmask 255.255.255.0 { 8 | option domain-name "DOMAIN"; 9 | option domain-name-servers INTERFACE_IP; 10 | range DHCP_SUBNET_FIRST DHCP_SUBNET_LAST; 11 | option routers INTERFACE_IP; 12 | option broadcast-address DHCP_BASE.255; 13 | default-lease-time 86400; 14 | max-lease-time 172800; 15 | on commit { 16 | set clientIP = binary-to-ascii(10, 8, ".", leased-address); 17 | set clientHost = pick-first-value(option fqdn.hostname, option host-name, ""); 18 | execute("/usr/local/bin/dhcpd-hook.sh", "ipv4", "add", clientIP, clientHost, "DOMAIN"); 19 | } 20 | on release { 21 | set clientIP = binary-to-ascii(10, 8, ".", leased-address); 22 | set clientHost = pick-first-value(option fqdn.hostname, option host-name, ""); 23 | execute("/usr/local/bin/dhcpd-hook.sh", "ipv4", "delete", clientIP, clientHost, "DOMAIN"); 24 | } 25 | on expiry { 26 | set clientIP = binary-to-ascii(10, 8, ".", leased-address); 27 | set clientHost = pick-first-value(option fqdn.hostname, option host-name, ""); 28 | execute("/usr/local/bin/dhcpd-hook.sh", "ipv4", "delete", clientIP, clientHost, "DOMAIN"); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /templates/cloud-init/user-data: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | package_upgrade: false 3 | resize_rootfs: True 4 | manage_etc_hosts: localhost 5 | 6 | cloud_final_modules: 7 | - [users-groups, always] 8 | 9 | users: 10 | - name: cbsd 11 | groups: [sudo] 12 | sudo: ["ALL=(ALL) NOPASSWD:ALL"] 13 | shell: 14 | ssh-authorized-keys: 15 | - ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQD1rC034OUhsG+EzB9U7hEGOFVGqDMLZuXCNcT/I+Q2IUWPZzLjTTv8DjQ7DsUNdKBysNOdHK0WW/H25xcugxqFMNagUuJKiJm3tHof94+Y2xhwtDrTRtKgKGWOjxFggF6CyX2x6FfOaTF7bnYzjW1aDs5waTPLZBBmhJstS1+AArXA3yJUWeHntxpYK8eFj0lk/wOQJ5KCyihcjAfV+1Vm8IiFKMIsT/KjCw/9jS8H6rz1Yg89XBQljj67mPMRwVxAYAhHqGJpZY7+UuX3udELI1+pNup9R7EtF9WKYCVJMxpdcMU67SNuZWw5O548CUxzzM17sM7MRZdXlQIAspE7 reggae 16 | lock-passwd: False 17 | passwd: $6$61V0w0dRFFiEcnm2$o8CLPIdRBVHP13LQizdp12NEGD91RfHSB.c6uKnr9m2m3ZCg7ASeGENMaDt0tffmo5RalKGjWiHCtScCtjYfs/ 18 | - name: root 19 | lock-passwd: False 20 | passwd: $6$h9pydrjL8JVn6vCO$9kkZInu99CT67.lnESajG4lVB.vGP6uF8otMFI.x9sYWeliDlSn7XS6GT0yTblGbO1Kb4av0ynipvXGIOCAOg1 21 | 22 | chpasswd: 23 | list: | 24 | cbsd:$6$61V0w0dRFFiEcnm2$o8CLPIdRBVHP13LQizdp12NEGD91RfHSB.c6uKnr9m2m3ZCg7ASeGENMaDt0tffmo5RalKGjWiHCtScCtjYfs/ 25 | root:$6$h9pydrjL8JVn6vCO$9kkZInu99CT67.lnESajG4lVB.vGP6uF8otMFI.x9sYWeliDlSn7XS6GT0yTblGbO1Kb4av0ynipvXGIOCAOg1 26 | expire: False 27 | -------------------------------------------------------------------------------- /templates/cbsd.conf.tpl: -------------------------------------------------------------------------------- 1 | # DO NOT EDIT THIS FILE. PLEASE USE INSTEAD: 2 | # cbsd jconfig jname=SERVICE 3 | relative_path="1"; 4 | jname="SERVICE"; 5 | path="CBSD_WORKDIR/jails/SERVICE"; 6 | host_hostname="SERVICE.DOMAIN"; 7 | ip4_addr="DHCP"; 8 | mount_devfs="1"; 9 | allow_mount="1"; 10 | allow_devfs="1"; 11 | allow_nullfs="1"; 12 | mount_fstab="CBSD_WORKDIR/jails-fstab/fstab.SERVICE"; 13 | arch="native"; 14 | mkhostsfile="1"; 15 | devfs_ruleset="DEVFS_RULESET"; 16 | ver="VERSION"; 17 | basename=""; 18 | baserw="0"; 19 | mount_src="0"; 20 | mount_obj="0"; 21 | mount_kernel="0"; 22 | mount_ports="0"; 23 | data="CBSD_WORKDIR/jails-data/SERVICE-data"; 24 | vnet="0"; 25 | applytpl="1"; 26 | mdsize="0"; 27 | rcconf="CBSD_WORKDIR/jails-rcconf/rc.conf_SERVICE"; 28 | floatresolv="1"; 29 | zfs_snapsrc=""; 30 | 31 | exec_poststart="0"; 32 | exec_poststop="0"; 33 | exec_prestart="0"; 34 | exec_prestop="0"; 35 | 36 | exec_master_poststart="0"; 37 | exec_master_poststop="0"; 38 | exec_master_prestart="0"; 39 | exec_master_prestop="0"; 40 | pkg_bootstrap="0"; 41 | with_img_helpers=""; 42 | interface="INTERFACE"; 43 | jailskeldir="CBSD_WORKDIR/share/FreeBSD-jail-reggae-skel"; 44 | jail_profile="reggae"; 45 | systemskeldir="CBSD_WORKDIR/share/jail-system-reggae"; 46 | exec_start="/bin/sh /etc/rc" 47 | exec_stop="/bin/sh /etc/rc.shutdown" 48 | emulator="jail" 49 | -------------------------------------------------------------------------------- /scripts/init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ -f "/usr/local/etc/reggae.conf" ]; then 6 | . "/usr/local/etc/reggae.conf" 7 | fi 8 | 9 | SCRIPT_DIR=$(dirname $0) 10 | . "${SCRIPT_DIR}/default.conf" 11 | 12 | 13 | PROJECT_ROOT=$(readlink -f ${SCRIPT_DIR}/..) 14 | MAKEFILE="Makefile.service" 15 | PROVISIONERS=$@ 16 | SERVICE_NAME=$(basename ${PWD}) 17 | case ${SERVICE_NAME} in 18 | jail*) 19 | SERVICE_NAME=$(echo ${SERVICE_NAME} | cut -b 5-) 20 | ;; 21 | esac 22 | case ${SERVICE_NAME} in 23 | -*) 24 | SERVICE_NAME=$(echo ${SERVICE_NAME} | cut -b 2-) 25 | ;; 26 | esac 27 | 28 | echo -n "Generating Makefile ... " 29 | sed -e "s;SERVICE_NAME;${SERVICE_NAME};g" "${PROJECT_ROOT}/templates/${MAKEFILE}" >Makefile 30 | echo "done" 31 | 32 | echo -n "Generating .gitignore ... " 33 | cp "${PROJECT_ROOT}/templates/gitignore" .gitignore 34 | echo "done" 35 | 36 | echo -n "Generating tests ..." 37 | mkdir bin 38 | echo "#!/bin/sh" >bin/test.sh 39 | chmod +x bin/test.sh 40 | echo "done" 41 | 42 | rm -rf provisioners.mk 43 | for provisioner in ${PROVISIONERS}; do 44 | echo ".include <\${REGGAE_PATH}/mk/${provisioner}.mk>" >>provisioners.mk 45 | if [ -d "${PROJECT_ROOT}"/skel/${provisioner} ]; then 46 | echo -n "Populating from skel for ${provisioner} ... " 47 | cp -r "${PROJECT_ROOT}"/skel/${provisioner}/* . 48 | echo "done" 49 | fi 50 | done 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2017, Goran Mekić 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /scripts/puppet-provision.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | SERVICE="${1}" 6 | TYPE="${2}" 7 | 8 | if [ -z "${SERVICE}" ]; then 9 | echo "Usage: ${0} " 2>&1 10 | exit 1 11 | fi 12 | 13 | JAIL_PATH=$(jls -j ${SERVICE} path) 14 | 15 | init() { 16 | if [ "${TYPE}" = "jail" ]; then 17 | mount_nullfs "${PWD}/puppet/manifests" "${JAIL_PATH}/usr/local/etc/puppet/manifests" 18 | reggae jexec ${SERVICE} pkg install -y puppet5 19 | elif [ "${TYPE}" = "bhyve" ]; then 20 | reggae ssh provision ${SERVICE} mdo mount_nullfs /usr/src/puppet/manifests /usr/local/etc/puppet/manifests 21 | reggae ssh provision ${SERVICE} mdo pkg install -y puppet5 22 | fi 23 | } 24 | 25 | cleanup() { 26 | if [ "${TYPE}" = "jail" ]; then 27 | umount "${JAIL_PATH}/usr/local/etc/puppet/manifests" 28 | elif [ "${TYPE}" = "bhyve" ]; then 29 | reggae ssh provision ${SERVICE} mdo umount /usr/local/etc/puppet/manifests 30 | fi 31 | } 32 | 33 | if [ -z "${SERVICE}" ]; then 34 | echo "Usage: ${0} " 2>&1 35 | exit 1 36 | fi 37 | 38 | trap "cleanup" HUP INT ABRT BUS TERM EXIT 39 | init 40 | 41 | if [ "${TYPE}" = "jail" ]; then 42 | reggae jexec ${SERVICE} puppet apply /usr/local/etc/puppet/manifests/site.pp 43 | elif [ "${TYPE}" = "bhyve" ]; then 44 | reggae ssh provision ${SERVICE} mdo puppet apply /usr/local/etc/puppet/manifests/site.pp 45 | else 46 | echo "Type ${TYPE} unknown!" >&2 47 | exit 1 48 | fi 49 | -------------------------------------------------------------------------------- /scripts/chef-provision.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | SERVICE="${1}" 6 | TYPE="${2}" 7 | 8 | if [ -z "${SERVICE}" ]; then 9 | echo "Usage: ${0} " 2>&1 10 | exit 1 11 | fi 12 | 13 | JAIL_PATH=$(jls -j ${SERVICE} path) 14 | 15 | 16 | init() { 17 | if [ "${TYPE}" = "jail" ]; then 18 | reggae jexec ${SERVICE} pkg install -y rubygem-chef 19 | mkdir ${JAIL_PATH}/etc/chef >/dev/null 2>&1 || true 20 | mkdir ${JAIL_PATH}/root/chef >/dev/null 2>&1 || true 21 | mount_nullfs "${PWD}/chef" "${JAIL_PATH}/root/chef" 22 | elif [ "${TYPE}" = "bhyve" ]; then 23 | reggae ssh provision ${SERVICE} mdo mkdir /etc/chef >/dev/null 2>&1 || true 24 | reggae ssh provision ${SERVICE} mdo pkg install -y rubygem-chef 25 | fi 26 | } 27 | 28 | cleanup() { 29 | if [ "${TYPE}" = "jail" ]; then 30 | rm -rf "${JAIL_PATH}/root/chef/nodes" 31 | umount "${JAIL_PATH}/root/chef" 32 | elif [ "${TYPE}" = "bhyve" ]; then 33 | reggae ssh provision ${SERVICE} mdo rm -rf /usr/src/chef/nodes 34 | fi 35 | } 36 | 37 | trap "cleanup" HUP INT ABRT BUS TERM EXIT 38 | init 39 | 40 | if [ "${TYPE}" = "jail" ]; then 41 | reggae jexec ${SERVICE} "cd /root/chef && chef-client --local-mode --override-runlist core" 42 | elif [ "${TYPE}" = "bhyve" ]; then 43 | reggae ssh provision ${SERVICE} "cd /usr/src/chef && mdo chef-client --local-mode --override-runlist core" 44 | else 45 | echo "Type ${TYPE} unknown!" >&2 46 | exit 1 47 | fi 48 | -------------------------------------------------------------------------------- /scripts/service.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | SOCKET_DIR=${1} 6 | PID_FILE=${2} 7 | 8 | if [ -z "${SOCKET_DIR}" -o -z "${PID_FILE}" ]; then 9 | echo "Usage: $0 " >&2 10 | exit 1 11 | fi 12 | 13 | SOCKET="${SOCKET_DIR}/reggae.sock" 14 | MYPID="" 15 | 16 | 17 | cleanup() { 18 | pkill -P ${MYPID} 19 | rm -rf ${SOCKET} 20 | } 21 | 22 | trap cleanup HUP INT ABRT BUS TERM EXIT 23 | 24 | 25 | register_v4() { 26 | pfctl -t reggae -T add $1 27 | } 28 | 29 | 30 | register_v6() { 31 | pfctl -t reggae6 -T add $1 32 | } 33 | 34 | 35 | unregister_v4() { 36 | pfctl -t reggae -T delete $1 37 | } 38 | 39 | 40 | unregister_v6() { 41 | pfctl -t reggae6 -T delete $1 42 | } 43 | 44 | 45 | run() { 46 | rm -rf "${SOCKET}" 47 | /usr/bin/nc -k -l -U "${SOCKET}" | while read action inet ip fqdn; do 48 | if [ "${action}" = "register" ]; then 49 | if [ "${inet}" = "ipv4" ]; then 50 | register_v4 ${ip} 51 | elif [ "${inet}" = "ipv6" ]; then 52 | register_v6 ${ip} 53 | fi 54 | elif [ "${action}" = "unregister" ]; then 55 | if [ "${inet}" = "ipv4" ]; then 56 | unregister_v4 ${ip} 57 | elif [ "${inet}" = "ipv6" ]; then 58 | unregister_v6 ${ip} 59 | fi 60 | fi 61 | first=$(echo ${fqdn} | cut -f 1 -d '.') 62 | if [ ! -z "${first}" ]; then 63 | /usr/sbin/local-unbound-control flush ${fqdn} 64 | fi 65 | done 66 | } 67 | 68 | run & 69 | MYPID=$! 70 | echo $$ >"${PID_FILE}" 71 | sleep 0.3 72 | chmod g+w "${SOCKET}" 73 | chown root:216 "${SOCKET}" 74 | wait 75 | -------------------------------------------------------------------------------- /scripts/utils.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | 6 | next_id() { 7 | NEXT_ID=$(cat /etc/jail.conf.d/*.conf 2>/dev/null || true | grep -s '$id = ' || true) 8 | if [ -z "${NEXT_ID}" ]; then 9 | echo 0 10 | else 11 | expr $(cat /etc/jail.conf.d/*.conf | \ 12 | grep '$id' | \ 13 | cut -f 1 -d ';' | \ 14 | awk -F '= ' '{print $2}' | \ 15 | sort -n | \ 16 | tail -n 1 \ 17 | ) + 1 18 | fi 19 | } 20 | 21 | 22 | check() { 23 | NAME="${1}" 24 | CHROOT="${2}" 25 | if [ -e "${CHROOT}" ]; then 26 | echo "${CHROOT} already exists!" >&2 27 | exit 1 28 | fi 29 | if [ -e "/etc/jail.conf.d/${NAME}.conf" ]; then 30 | echo "${NAME}.conf already defined in /etc/jail.conf.d!" >&2 31 | exit 1 32 | fi 33 | } 34 | 35 | 36 | get_backend() { 37 | JNAME="${1}" 38 | BASE_WORKDIR=$(reggae get-config BASE_WORKDIR) 39 | CBSD_WORKDIR=$(sysrc -s cbsd -n cbsd_workdir 2>/dev/null || true) 40 | JAIL_PATH=$(jls -j ${JNAME} path) 41 | if [ "${JAIL_PATH}" = "${BASE_WORKDIR}/${JNAME}" ]; then 42 | echo "base" 43 | elif [ ! -z "${CBSD_WORKDIR}" -a "${JAIL_PATH}" = "${CBSD_WORKDIR}/jails/${JNAME}" ]; then 44 | echo "cbsd" 45 | else 46 | echo "Unsupported jail backend" >&2 47 | exit 1 48 | fi 49 | } 50 | 51 | 52 | execute_command() { 53 | JNAME="${1}" 54 | COMMAND="${2}" 55 | BACKEND=$(get_backend "${JNAME}") 56 | if [ "${BACKEND}" = "base" ]; then 57 | jexec -U "${JAIL_USER}" "${JNAME}" ${COMMAND} 58 | elif [ "${BACKEND}" = "cbsd" ]; then 59 | cbsd jexec jname="${JNAME}" user="${JAIL_USER}" cmd="${COMMAND}" 60 | fi 61 | } 62 | -------------------------------------------------------------------------------- /cbsd-profile/skel/etc/passwd: -------------------------------------------------------------------------------- 1 | # $FreeBSD: head/etc/master.passwd 256365 2013-10-12 06:06:53Z rpaulo $ 2 | # 3 | root:*:0:0:Charlie &:/root:/bin/csh 4 | toor:*:0:0:Bourne-again Superuser:/root: 5 | daemon:*:1:1:Owner of many system processes:/root:/usr/sbin/nologin 6 | operator:*:2:5:System &:/:/usr/sbin/nologin 7 | bin:*:3:7:Binaries Commands and Source:/:/usr/sbin/nologin 8 | tty:*:4:65533:Tty Sandbox:/:/usr/sbin/nologin 9 | kmem:*:5:65533:KMem Sandbox:/:/usr/sbin/nologin 10 | games:*:7:13:Games pseudo-user:/usr/games:/usr/sbin/nologin 11 | news:*:8:8:News Subsystem:/:/usr/sbin/nologin 12 | man:*:9:9:Mister Man Pages:/usr/share/man:/usr/sbin/nologin 13 | sshd:*:22:22:Secure Shell Daemon:/var/empty:/usr/sbin/nologin 14 | smmsp:*:25:25:Sendmail Submission User:/var/spool/clientmqueue:/usr/sbin/nologin 15 | mailnull:*:26:26:Sendmail Default User:/var/spool/mqueue:/usr/sbin/nologin 16 | bind:*:53:53:Bind Sandbox:/:/usr/sbin/nologin 17 | unbound:*:59:59:Unbound DNS Resolver:/var/unbound:/usr/sbin/nologin 18 | proxy:*:62:62:Packet Filter pseudo-user:/nonexistent:/usr/sbin/nologin 19 | _pflogd:*:64:64:pflogd privsep user:/var/empty:/usr/sbin/nologin 20 | _dhcp:*:65:65:dhcp programs:/var/empty:/usr/sbin/nologin 21 | uucp:*:66:66:UUCP pseudo-user:/var/spool/uucppublic:/usr/local/libexec/uucp/uucico 22 | pop:*:68:6:Post Office Owner:/nonexistent:/usr/sbin/nologin 23 | auditdistd:*:78:77:Auditdistd unprivileged user:/var/empty:/usr/sbin/nologin 24 | www:*:80:80:World Wide Web Owner:/nonexistent:/usr/sbin/nologin 25 | hast:*:845:845:HAST unprivileged user:/var/empty:/usr/sbin/nologin 26 | nobody:*:65534:65534:Unprivileged user:/nonexistent:/usr/sbin/nologin 27 | provision:*:666:666:Provision:/home/provision:/bin/tcsh 28 | -------------------------------------------------------------------------------- /id_rsa: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpAIBAAKCAQEA9awtN+DlIbBvhMwfVO4RBjhVRqgzC2blwjXE/yPkNiFFj2cy 3 | 4007/A40Ow7FDXSgcrDTnRytFlvx9ucXLoMahTDWoFLiSoiZt7R6H/ePmNsYcLQ6 4 | 00bSoChljo8RYIBegsl9sehXzmkxe252M41tWg7OcGkzy2QQZoSbLUtfgAK1wN8i 5 | VFnh57caWCvHhY9JZP8DkCeSgsooXIwH1ftVZvCIhSjCLE/yowsP/Y0vB+q89WIP 6 | PVwUJY4+u5jzEcFcQGAIR6hiaWWO/lLl97nRCyNfqTbqfUexLRfVimAlSTMaXXDF 7 | Ou0jbmVsOTuePAlMc8zNe7DOzEWXV5UCALKROwIDAQABAoIBAQCqKRyU1JfAMuW7 8 | NGsLN23hQgmGzB+26QmA8B9HnUOHXppAjnlHyQogNnJk6YEBJeOwLNwVuXQFxZ+d 9 | pUiANdybnk06dM46U80s2buxApaaiD6waZVJG4ft2K0nBd9CWQedTRRbspOG64OT 10 | e9oxMOcp9pF0eNmgKenWKEkXIVq/XUXARGrBQVCGJDVgebPrLJ0DYq0j/el1rRtS 11 | YTcGwpHcrc1OSFft6OrLzbfvy6TrHzSfJHQ1rGWam5+xsfjxlmkaps/4vBqmzIHK 12 | 5uCbOWLhGEefwyJpLYm+1nryd6AQuYwpVOR2z+1fUOyuAb8U4uM3T6u5rggg4MQ6 13 | NFFc1ziBAoGBAPuILeq+znbg6leejD/h98PE0Qp3iM+dSIKsXjjR0RX3pROhvoPU 14 | PQfZC+1SqlImVGDWcWFx2caOF0QZXa2jvxW6/GdawNCTOikCfrUc+mwg2OPBHjJp 15 | T3HFdDj8ynxJmrN73KQJ3Fw+yqoqJAbwEYSUD6Dnpb+pp0EYbH5jwU1BAoGBAPoJ 16 | WingRPadw1yxz9NRaHmecb9JQB1JCBLXMlFtZyWPBnYclgL1DdT0Nkf/v4bGzGIk 17 | XAKtKKAsPiKsX5wDC6lcaAp6uVypOIHXWRGvAyXwuCAx0yuKyp+ah6g14pIMe+wf 18 | t0EkUVhgg/Ib6g5bcAXaOsv8fChPonnOBipgTrN7AoGBAMyFJhDBpM80gldMK22m 19 | JvefiPmhyDRIBzV5QgOhVwktm6Qi1+4JHLbM3M3TcXnqgKFcvEQndpPj5TcSCQGv 20 | KyhYKfM/75eonpnJ1Y0eSuCwtKo71HnY9yfjDWVo5pu4nXljNTyMaAj5ZYCHU1Pw 21 | z82lNi/3KuZ04/IiEdWS9xIBAoGAGX1ElMpJHX79wIBb+GXvKZ7OZ7q274VXblxD 22 | w+tMPZb0CKxnWovSyifPNM3Mn5e6lDKyso8mehWoi+5YnNXupWhHLvJN3TVfDlV+ 23 | vf/CaWa9zoJlzaWLfHPLaol7vHnLVEnza4+hP0oviUnxNV967w3NOqhVm+JqZNJs 24 | 7Hr+6usCgYBV6fCsaWYmTlSWY6bKMcSRniTC4I9FnvaVKnTHFplvTFyE74aUIlQF 25 | CY1F+OmolQgqRFybCps2oIjxNI4VfNUBu6gceXB3b+o/0eM8i1rkduLLooCr6tBs 26 | SPJ6F96DUJAZqxWxQjC9QsraXDWJxOeIpxHhMcwXCApVXYDJsZVK2g== 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /templates/cbsd-vnet.conf.tpl: -------------------------------------------------------------------------------- 1 | # DO NOT EDIT THIS FILE. PLEASE USE INSTEAD: 2 | # cbsd jconfig jname=SERVICE 3 | relative_path="1"; 4 | jname="SERVICE"; 5 | path="CBSD_WORKDIR/jails/SERVICE"; 6 | data="CBSD_WORKDIR/jails-data/SERVICE-data"; 7 | rcconf="CBSD_WORKDIR/jails-rcconf/rc.conf_SERVICE"; 8 | 9 | # FQDN for environment 10 | host_hostname="SERVICE.DOMAIN"; 11 | # default environment IP 12 | ip4_addr="REALDHCP"; 13 | 14 | # start with system boot? 15 | astart="0"; 16 | 17 | # first NIC hardware address 18 | nic_hwaddr="0"; 19 | 20 | # create from ZFS snapshot? 21 | zfs_snapsrc=""; 22 | # run immediately upon creation 23 | runasap="0"; 24 | # bind to interface 25 | interface="INTERFACE"; 26 | rctl_nice="0" 27 | jailskeldir="CBSD_WORKDIR/share/FreeBSD-jail-reggae-skel"; 28 | systemskeldir="CBSD_WORKDIR/share/jail-system-reggae"; 29 | jail_profile="reggae"; 30 | mount_devfs="1"; 31 | allow_mount="1"; 32 | allow_devfs="1"; 33 | allow_nullfs="1"; 34 | allow_fusefs="0"; 35 | allow_raw_sockets="0"; 36 | mount_fstab="CBSD_WORKDIR/jails-fstab/fstab.SERVICE"; 37 | arch="native"; 38 | mkhostsfile="1"; 39 | devfs_ruleset="DEVFS_RULESET"; 40 | ver="VERSION"; 41 | basename=""; 42 | baserw="0"; 43 | mount_src="0"; 44 | mount_obj="0"; 45 | mount_kernel="0"; 46 | mount_ports="0"; 47 | vnet="1"; 48 | applytpl="1"; 49 | mdsize="0"; 50 | floatresolv="1"; 51 | 52 | exec_poststart="0"; 53 | exec_poststop=""; 54 | exec_prestart="0"; 55 | exec_prestop="0"; 56 | 57 | exec_master_poststart="0"; 58 | exec_master_poststop="0"; 59 | exec_master_prestart="0"; 60 | exec_master_prestop="0"; 61 | 62 | pkg_bootstrap="0"; 63 | with_img_helpers=""; 64 | 65 | allow_reserved_ports="1"; 66 | 67 | persist="1"; 68 | childrenmax="0"; 69 | enforce_statfs="1"; 70 | sysrc_enable=""; 71 | exec_start="/bin/sh /etc/rc" 72 | exec_stop="/bin/sh /etc/rc.shutdown" 73 | emulator="jail" 74 | -------------------------------------------------------------------------------- /templates/master.conf: -------------------------------------------------------------------------------- 1 | # DO NOT EDIT THIS FILE. PLEASE USE INSTEAD: 2 | # cbsd jconfig jname=SERVICE 3 | relative_path="1"; 4 | jname="SERVICE"; 5 | path="CBSD_WORKDIR/jails/SERVICE"; 6 | data="CBSD_WORKDIR/jails-data/SERVICE-data"; 7 | rcconf="CBSD_WORKDIR/jails-rcconf/rc.conf_SERVICE"; 8 | 9 | # FQDN for environment 10 | host_hostname="SERVICE.DOMAIN"; 11 | # default environment IP 12 | ip4_addr="MASTER_IP"; 13 | ci_gw4="INTERFACE_IP" 14 | 15 | # start with system boot? 16 | astart="1"; 17 | 18 | # first NIC hardware address 19 | nic_hwaddr="0"; 20 | 21 | # create from ZFS snapshot? 22 | zfs_snapsrc=""; 23 | # run immediately upon creation 24 | runasap="0"; 25 | # bind to interface 26 | interface="auto"; 27 | rctl_nice="0" 28 | jailskeldir="CBSD_WORKDIR/share/FreeBSD-jail-reggae-skel"; 29 | systemskeldir="CBSD_WORKDIR/share/jail-system-reggae"; 30 | jail_profile="reggae"; 31 | mount_devfs="1"; 32 | allow_mount="1"; 33 | allow_devfs="1"; 34 | allow_nullfs="1"; 35 | allow_fusefs="0"; 36 | allow_raw_sockets="0"; 37 | mount_fstab="CBSD_WORKDIR/jails-fstab/fstab.SERVICE"; 38 | arch="native"; 39 | mkhostsfile="1"; 40 | devfs_ruleset="DEVFS_RULESET"; 41 | ver="VERSION"; 42 | basename=""; 43 | baserw="0"; 44 | mount_src="0"; 45 | mount_obj="0"; 46 | mount_kernel="0"; 47 | mount_ports="0"; 48 | vnet="1"; 49 | applytpl="1"; 50 | mdsize="0"; 51 | floatresolv="1"; 52 | 53 | exec_poststart="0"; 54 | exec_poststop=""; 55 | exec_prestart="0"; 56 | exec_prestop="0"; 57 | 58 | exec_master_poststart="0"; 59 | exec_master_poststop="0"; 60 | exec_master_prestart="0"; 61 | exec_master_prestop="0"; 62 | 63 | pkg_bootstrap="0"; 64 | with_img_helpers=""; 65 | 66 | allow_reserved_ports="1"; 67 | 68 | persist="1"; 69 | childrenmax="0"; 70 | enforce_statfs="1"; 71 | sysrc_enable=""; 72 | exec_start="/bin/sh /etc/rc" 73 | exec_stop="/bin/sh /etc/rc.shutdown" 74 | emulator="jail" 75 | 76 | -------------------------------------------------------------------------------- /mk/use.mk: -------------------------------------------------------------------------------- 1 | PRE_SERVICES = 2 | USED_SERVICES = 3 | POST_SERVICES = 4 | 5 | USE_PRE_ldap ?= https://github.com/mekanix/jail-ldap 6 | USE_PRE_letsencrypt ?= https://github.com/mekanix/jail-letsencrypt 7 | USE_PRE_mongodb ?= https://github.com/mekanix/jail-mongodb 8 | USE_PRE_mysql ?= https://github.com/mekanix/jail-mysql 9 | USE_PRE_postgresql ?= https://github.com/mekanix/jail-postgresql 10 | USE_PRE_redis ?= https://github.com/mekanix/jail-redis 11 | 12 | USE_USED_ejabberd ?= https://github.com/mekanix/jail-ejabberd 13 | USE_USED_forgejo ?= https://github.com/mekanix/jail-forgejo 14 | USE_USED_gitolite ?= https://github.com/mekanix/jail-gitolite 15 | USE_USED_mail ?= https://github.com/mekanix/jail-mail 16 | USE_USED_moodle ?= https://github.com/mekanix/jail-moodle 17 | USE_USED_nextcloud ?= https://github.com/mekanix/jail-nextcloud 18 | USE_USED_opigno ?= https://github.com/mekanix/jail-opigno 19 | USE_USED_peertube ?= https://github.com/mekanix/jail-peertube 20 | USE_USED_polipo ?= https://github.com/mekanix/jail-polipo 21 | USE_USED_prosody ?= https://github.com/mekanix/jail-prosody 22 | USE_USED_radicale ?= https://github.com/mekanix/jail-radicale 23 | USE_USED_turn ?= https://github.com/mekanix/jail-turn 24 | USE_USED_webmail ?= https://github.com/mekanix/jail-webmail 25 | USE_USED_wordpress ?= https://github.com/mekanix/jail-wordpress 26 | USE_USED_znc ?= https://github.com/mekanix/jail-znc 27 | 28 | USE_POST_nginx ?= https://github.com/mekanix/jail-nginx 29 | 30 | .for use in ${USE} 31 | .if defined(USE_PRE_${use}) 32 | PRE_SERVICES += ${use} ${USE_PRE_${use}} 33 | .elif defined(USE_POST_${use}) 34 | POST_SERVICES += ${use} ${USE_POST_${use}} 35 | .elif defined(USE_USED_${use}) 36 | USED_SERVICES += ${use} ${USE_USED_${use}} 37 | .elif defined(USE_POST_${use}) 38 | POST_SERVICES += ${use} ${USE_POST_${use}} 39 | .endif 40 | .endfor 41 | 42 | ALL_SERVICES = ${PRE_SERVICES} ${USED_SERVICES} ${SERVICES} ${POST_SERVICES} 43 | -------------------------------------------------------------------------------- /cbsd-profile/skel/etc/master.passwd: -------------------------------------------------------------------------------- 1 | # $FreeBSD: head/etc/master.passwd 256365 2013-10-12 06:06:53Z rpaulo $ 2 | # 3 | root:$6$cXHa9mBH7sXLAhyB$/AJ5Wg5bTptm7su.gaUPVahZCWtOpsRQjjkyagjlNV1Uz5nDNzj7LXh13wCts3vRrErdyjgM/nZRmyPg3He0C0:0:0::0:0:Charlie &:/root:/bin/csh 4 | toor:*:0:0::0:0:Bourne-again Superuser:/root: 5 | daemon:*:1:1::0:0:Owner of many system processes:/root:/usr/sbin/nologin 6 | operator:*:2:5::0:0:System &:/:/usr/sbin/nologin 7 | bin:*:3:7::0:0:Binaries Commands and Source:/:/usr/sbin/nologin 8 | tty:*:4:65533::0:0:Tty Sandbox:/:/usr/sbin/nologin 9 | kmem:*:5:65533::0:0:KMem Sandbox:/:/usr/sbin/nologin 10 | games:*:7:13::0:0:Games pseudo-user:/usr/games:/usr/sbin/nologin 11 | news:*:8:8::0:0:News Subsystem:/:/usr/sbin/nologin 12 | man:*:9:9::0:0:Mister Man Pages:/usr/share/man:/usr/sbin/nologin 13 | sshd:*:22:22::0:0:Secure Shell Daemon:/var/empty:/usr/sbin/nologin 14 | smmsp:*:25:25::0:0:Sendmail Submission User:/var/spool/clientmqueue:/usr/sbin/nologin 15 | mailnull:*:26:26::0:0:Sendmail Default User:/var/spool/mqueue:/usr/sbin/nologin 16 | bind:*:53:53::0:0:Bind Sandbox:/:/usr/sbin/nologin 17 | unbound:*:59:59::0:0:Unbound DNS Resolver:/var/unbound:/usr/sbin/nologin 18 | proxy:*:62:62::0:0:Packet Filter pseudo-user:/nonexistent:/usr/sbin/nologin 19 | _pflogd:*:64:64::0:0:pflogd privsep user:/var/empty:/usr/sbin/nologin 20 | _dhcp:*:65:65::0:0:dhcp programs:/var/empty:/usr/sbin/nologin 21 | uucp:*:66:66::0:0:UUCP pseudo-user:/var/spool/uucppublic:/usr/local/libexec/uucp/uucico 22 | pop:*:68:6::0:0:Post Office Owner:/nonexistent:/usr/sbin/nologin 23 | auditdistd:*:78:77::0:0:Auditdistd unprivileged user:/var/empty:/usr/sbin/nologin 24 | www:*:80:80::0:0:World Wide Web Owner:/nonexistent:/usr/sbin/nologin 25 | hast:*:845:845::0:0:HAST unprivileged user:/var/empty:/usr/sbin/nologin 26 | nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/usr/sbin/nologin 27 | provision:$6$0whzYy257oWfQ7GB$VqssZmNer1g4D2ry6s8qJSDitZWnSsxjnjPokHu2EP13f6NfvvIv9mVG31Fp1K2AMD.AdGQTqll1FwZAz6tda1:666:666::0:0:Provision:/home/provision:/bin/tcsh 28 | -------------------------------------------------------------------------------- /cbsd-profile/skel/etc/mail/aliases: -------------------------------------------------------------------------------- 1 | # $FreeBSD: head/etc/mail/aliases 243752 2012-12-01 15:11:46Z rwatson $ 2 | # @(#)aliases 5.3 (Berkeley) 5/24/90 3 | # 4 | # Aliases in this file will NOT be expanded in the header from 5 | # Mail, but WILL be visible over networks. 6 | # 7 | # >>>>>>>>>> The program "newaliases" must be run after 8 | # >> NOTE >> this file is updated for any changes to 9 | # >>>>>>>>>> show through to sendmail. 10 | # 11 | # 12 | # See also RFC 2142, `MAILBOX NAMES FOR COMMON SERVICES, ROLES 13 | # AND FUNCTIONS', May 1997 14 | # http://tools.ietf.org/html/rfc2142 15 | 16 | # Pretty much everything else in this file points to "root", so 17 | # you would do well in either reading root's mailbox or forwarding 18 | # root's email from here. 19 | root: /dev/null 20 | # root: me@my.domain 21 | 22 | # Basic system aliases -- these MUST be present 23 | MAILER-DAEMON: postmaster 24 | postmaster: root 25 | 26 | # General redirections for pseudo accounts 27 | _dhcp: root 28 | _pflogd: root 29 | auditdistd: root 30 | bin: root 31 | bind: root 32 | daemon: root 33 | games: root 34 | hast: root 35 | kmem: root 36 | mailnull: postmaster 37 | man: root 38 | news: root 39 | nobody: root 40 | operator: root 41 | pop: root 42 | proxy: root 43 | smmsp: postmaster 44 | sshd: root 45 | system: root 46 | toor: root 47 | tty: root 48 | usenet: news 49 | uucp: root 50 | 51 | # Well-known aliases -- these should be filled in! 52 | # manager: 53 | # dumper: 54 | 55 | # BUSINESS-RELATED MAILBOX NAMES 56 | # info: 57 | # marketing: 58 | # sales: 59 | # support: 60 | 61 | # NETWORK OPERATIONS MAILBOX NAMES 62 | abuse: root 63 | # noc: root 64 | security: root 65 | 66 | # SUPPORT MAILBOX NAMES FOR SPECIFIC INTERNET SERVICES 67 | ftp: root 68 | ftp-bugs: ftp 69 | # hostmaster: root 70 | # webmaster: root 71 | # www: webmaster 72 | 73 | # NOTE: /var/msgs and /var/msgs/bounds must be owned by sendmail's 74 | # DefaultUser (defaults to mailnull) for the msgs alias to work. 75 | # 76 | # msgs: "| /usr/bin/msgs -s" 77 | 78 | # bit-bucket: /dev/null 79 | # dev-null: bit-bucket 80 | -------------------------------------------------------------------------------- /scripts/update-base.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ -f "/usr/local/etc/reggae.conf" ]; then 6 | . "/usr/local/etc/reggae.conf" 7 | fi 8 | 9 | SCRIPT_DIR=$(dirname $0) 10 | . "${SCRIPT_DIR}/default.conf" 11 | 12 | 13 | if [ "${BACKEND}" = "cbsd" ]; then 14 | cbsd baseupdate 15 | elif [ "${BACKEND}" = "base" ]; then 16 | JAIL="${1}" 17 | export PAGER=cat 18 | if [ "${PKG_PROXY}" != "no" ]; then 19 | export HTTP_PROXY="${PKG_PROXY}" 20 | fi 21 | if [ "${RUST}" = "YES" ]; then 22 | rustdate=$(which freebsd-rustdate || true) 23 | unset HTTP_PROXY 24 | if [ -z "${rustdate}" ]; then 25 | jexec "${jail_name}" pkg install -y freebsd-rustdate 26 | fi 27 | fi 28 | if [ -z "${JAIL}" ]; then 29 | cd "${BASE_WORKDIR}" 30 | jls -N | egrep -v ' *JID' | egrep -v ' ^svcj' | awk '{print $1}' | while read jail_name; do 31 | if [ -x "${jail_name}/bin/freebsd-version" ]; then 32 | export CURRENTLY_RUNNING="$(jexec "${jail_name}" freebsd-version -u)" 33 | CURRENTLY_RUNNING_FLAVOR="$(echo "${CURRENTLY_RUNNING}" | cut -f 2 -d '-')" 34 | if [ "${CURRENTLY_RUNNING_FLAVOR}" = "RELEASE" ]; then 35 | echo "=== ${jail_name} ===" 36 | if [ "${RUST}" = "YES" ]; then 37 | JAIL_ROOT="$(jls -N -j ${jail_name} path)" 38 | ${rustdate} -b "${JAIL_ROOT}" fetch 39 | ${rustdate} -b "${JAIL_ROOT}" install -as 40 | else 41 | freebsd-update -j "${jail_name}" --not-running-from-cron fetch install 42 | echo 43 | fi 44 | fi 45 | fi 46 | done 47 | cd - 48 | elif [ -x "${BASE_WORKDIR}/${JAIL}/bin/freebsd-version" ]; then 49 | echo "=== ${JAIL} ===" 50 | if [ "${RUST}" = "YES" ]; then 51 | unset HTTP_PROXY 52 | JAIL_ROOT="$(jls -N -j ${jail_name} path)" 53 | ${rustdate} -b "${JAIL_ROOT}" fetch 54 | ${rustdate} -b "${JAIL_ROOT}" install -as 55 | else 56 | freebsd-update -j "${jail_name}" --not-running-from-cron fetch install 57 | fi 58 | else 59 | echo "No such jail \"${JAIL}\"!" >&2 60 | exit 1 61 | fi 62 | fi 63 | -------------------------------------------------------------------------------- /templates/linux.conf.tpl: -------------------------------------------------------------------------------- 1 | # DO NOT EDIT THIS FILE. PLEASE USE INSTEAD: 2 | # cbsd jconfig jname=SERVICE 3 | relative_path="1"; 4 | jname="SERVICE"; 5 | path="CBSD_WORKDIR/jails/SERVICE"; 6 | data="CBSD_WORKDIR/jails-data/SERVICE-data"; 7 | rcconf="CBSD_WORKDIR/jails-rcconf/rc.conf_SERVICE"; 8 | 9 | # FQDN for environment 10 | host_hostname="SERVICE.DOMAIN"; 11 | # default environment IP 12 | ip4_addr="DHCP,DHCPv6"; 13 | 14 | # defaultrouter in /etc/rc.conf? 15 | ci_gw4=""; 16 | 17 | # start with system boot? 18 | astart="0"; 19 | 20 | # first NIC hardware address 21 | nic_hwaddr="0"; 22 | 23 | # create from ZFS snapshot? 24 | zfs_snapsrc=""; 25 | zfs_encryption=""; 26 | # run immediately upon creation 27 | runasap="0"; 28 | # bind to interface 29 | interface="INTERFACE"; 30 | rctl_nice="1" 31 | customskel="/usr/local/cbsd/share/FreeBSD-jail-debian-bullseye-skel" 32 | jailsysskeldir="/usr/local/cbsd/share/FreeBSD-jail-debian-bullseye-system-skel" 33 | jail_profile="debian_bullseye" 34 | mount_devfs="1"; 35 | allow_mount="1"; 36 | allow_devfs="1"; 37 | allow_nullfs="1"; 38 | allow_fusefs="0"; 39 | allow_linsysfs="0"; 40 | allow_linprocfs="0"; 41 | allow_raw_sockets="0"; 42 | mount_fstab="CBSD_WORKDIR/jails-fstab/SERVICE/fstab"; 43 | mount_fstab_old="CBSD_WORKDIR/jails-fstab/fstab.SERVICE"; 44 | arch="native"; 45 | mkhostsfile="1"; 46 | devfs_ruleset="4"; 47 | ver="empty"; 48 | basename=""; 49 | baserw="1"; 50 | mount_src="0"; 51 | mount_obj="0"; 52 | mount_kernel="0"; 53 | mount_ports="1"; 54 | vnet="0"; 55 | applytpl="0"; 56 | mdsize="0"; 57 | floatresolv="1"; 58 | 59 | exec_poststart="0"; 60 | exec_poststop=""; 61 | exec_prestart="0"; 62 | exec_prestop="0"; 63 | 64 | exec_master_poststart="0"; 65 | exec_master_poststop="0"; 66 | exec_master_prestart="0"; 67 | exec_master_prestop="0"; 68 | 69 | pkg_bootstrap="0"; 70 | with_img_helpers=""; 71 | 72 | allow_reserved_ports="1"; 73 | allow_unprivileged_proc_debug="1"; 74 | 75 | persist="1"; 76 | childrenmax="0"; 77 | enforce_statfs="1"; 78 | sysrc_enable=""; 79 | 80 | mnt_start="0"; 81 | mnt_stop="0"; 82 | 83 | allow_mlock="0"; 84 | jailnic_temp_sql=""; 85 | fsquota=""; 86 | etcupdate_init="0"; 87 | exec_start="/bin/true" 88 | exec_stop="/bin/true" 89 | emulator="jail" 90 | -------------------------------------------------------------------------------- /scripts/salt-provision.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | CBSD_WORKDIR=$(sysrc -s cbsdd -n cbsd_workdir) 6 | SERVICE="${1}" 7 | TYPE="${2}" 8 | PY_VERSION_MAJOR="3" 9 | PY_VERSION_MINOR="8" 10 | PY_PREFIX="py${PY_VERSION_MAJOR}${PY_VERSION_MINOR}" 11 | 12 | if [ -z "${SERVICE}" ]; then 13 | echo "Usage: ${0} " 2>&1 14 | exit 1 15 | fi 16 | 17 | init() { 18 | if [ "${TYPE}" = "jail" ]; then 19 | JAIL_PATH=$(jls -j ${JNAME} path) 20 | reggae jexec ${SERVICE} pkg install -y ${PY_PREFIX}-salt 21 | mkdir -p "${JAIL_PATH}/usr/local/etc/salt/minion.d" >/dev/null 2>&1 || true 22 | mkdir -p "${JAIL_PATH}/usr/local/etc/salt/states" >/dev/null 2>&1 || true 23 | mount_nullfs "${PWD}/salt/states" "${JAIL_PATH}/usr/local/etc/salt/states" 24 | echo 'file_client: local' >"${JAIL_PATH}/usr/local/etc/salt/minion.d/reggae.conf" 25 | elif [ "${TYPE}" = "bhyve" ]; then 26 | reggae ssh provision ${SERVICE} mdo pkg install -y "${PY_PREFIX}-salt" 27 | reggae ssh provision ${SERVICE} mdo mkdir -p /usr/local/etc/salt/minion.d >/dev/null 2>&1 || true 28 | reggae ssh provision ${SERVICE} mdo mkdir -p /usr/local/etc/salt/states >/dev/null 2>&1 || true 29 | reggae ssh provision ${SERVICE} mdo mount_nullfs /usr/src/salt/states /usr/local/etc/salt/states 30 | reggae ssh provision ${SERVICE} 'echo file_client: local >reggae.conf' 31 | reggae ssh provision ${SERVICE} mdo mv reggae.conf /usr/local/etc/salt/minion.d/ 32 | fi 33 | } 34 | 35 | cleanup() { 36 | if [ "${TYPE}" = "jail" ]; then 37 | JAIL_PATH=$(jls -j ${JNAME} path) 38 | rm -rf "${JAIL_PATH}/usr/local/etc/salt/minion.d/reggae.conf" 39 | umount "${JAIL_PATH}/usr/local/etc/salt/states" 40 | elif [ "${TYPE}" = "bhyve" ]; then 41 | reggae ssh provision ${SERVICE} mdo rm -rf /usr/local/etc/salt/minion.d/reggae.conf 42 | reggae ssh provision ${SERVICE} mdo umount /usr/local/etc/salt/states 43 | fi 44 | } 45 | 46 | trap "cleanup" HUP INT ABRT BUS TERM EXIT 47 | init 48 | 49 | if [ "${TYPE}" = "jail" ]; then 50 | reggae jexec ${SERVICE} salt-call --local state.apply 51 | elif [ "${TYPE}" = "bhyve" ]; then 52 | reggae ssh provision ${SERVICE} mdo salt-call --local state.apply 53 | else 54 | echo "Type ${TYPE} unknown!" >&2 55 | exit 1 56 | fi 57 | -------------------------------------------------------------------------------- /scripts/pkg-upgrade.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ -f "/usr/local/etc/reggae.conf" ]; then 6 | . "/usr/local/etc/reggae.conf" 7 | fi 8 | 9 | ALL=${1} 10 | SCRIPT_DIR=$(dirname $0) 11 | PROJECT_DIR="${SCRIPT_DIR}/.." 12 | . "${SCRIPT_DIR}/default.conf" 13 | 14 | 15 | RUNNING_JAILS="" 16 | ALL_RUNNING_JAILS=$(jls host.hostname | cut -f 1 -d '.') 17 | 18 | for jname in ${ALL_RUNNING_JAILS}; do 19 | if [ -f "/etc/jail.conf.d/${jname}.conf" ]; then 20 | RUNNING_JAILS="${RUNNING_JAILS} ${jname}" 21 | fi 22 | done 23 | 24 | for jname in ${RUNNING_JAILS}; do 25 | echo "=== ${jname} ====" 26 | reggae jexec ${jname} pkg upgrade 27 | reggae jexec ${jname} pkg autoremove -y 28 | reggae jexec ${jname} pkg clean -y 29 | echo 30 | done 31 | 32 | if [ "${ALL}" = "all" ]; then 33 | if [ "${BACKEND}" = "base" ]; then 34 | for jail_version in $(ls -1d "${BASE_WORKDIR}"/*/bin/freebsd-version 2>/dev/null); do 35 | jail_name=$(echo "${jail_version}" | sed "s;${BASE_WORKDIR}/;;g" | cut -f 1 -d '/') 36 | skip="NO" 37 | for running in ${RUNNING_JAILS}; do 38 | if [ "${jail_name}" = "${running}" ]; then 39 | skip="YES" 40 | break 41 | fi 42 | done 43 | if [ "${skip}" = "NO" ]; then 44 | echo "=== ${jail_name} ===" 45 | pkg --chroot "${BASE_WORKDIR}/${jail_name}" upgrade 46 | pkg --chroot "${BASE_WORKDIR}/${jail_name}" autoremove -y 47 | pkg --chroot "${BASE_WORKDIR}/${jail_name}" clean -y 48 | echo 49 | fi 50 | done 51 | elif [ "${BACKEND}" = "cbsd" ]; then 52 | OFF_JAILS="" 53 | OFF_JAILS_RAW=$(env NOCOLOR=1 cbsd jls header=0 display=status,jname | grep '^Off ') 54 | 55 | skip="YES" 56 | for item in ${OFF_JAILS_RAW}; do 57 | if [ "${skip}" = "YES" ]; then 58 | skip="NO" 59 | else 60 | skip="YES" 61 | OFF_JAILS="${OFF_JAILS} ${item}" 62 | fi 63 | done 64 | 65 | for jname in ${OFF_JAILS}; do 66 | echo "=== ${jname} ====" 67 | cbsd jstart ${jname} 68 | cbsd jexec "jname=${jname}" pkg upgrade 69 | cbsd jexec "jname=${jname}" pkg autoremove -y 70 | cbsd jexec "jname=${jname}" pkg clean -y 71 | cbsd jstop ${jname} 72 | echo 73 | done 74 | fi 75 | fi 76 | -------------------------------------------------------------------------------- /doc/cbsd/README.md: -------------------------------------------------------------------------------- 1 | # CBSD integration 2 | 3 | Although Reggae could leave CBSD config as it is, it's more suitable to have CBSD aware of Reggae config. Reggae configures hooks, profile and jail skel to run commands on CBSD actions or to make CBSD usable without Reggae. 4 | 5 | By default, there is only one hook that Reggae installs and it does two things: 6 | * registeres jail in DNS server 7 | * add's jail IP to PF table (used for granting access and NAT) 8 | DNS registration is done via RNDC and keys, while for /dev/pf access inside jail, special /etc/devfs.rules entry is made but only if /etc/devfs.rules doesn't exist already, so be careful when doing custom configs: you have to add this in devfs: 9 | ``` 10 | [vnet=8] 11 | add include \$devfsrules_hide_all 12 | add include \$devfsrules_unhide_basic 13 | add include \$devfsrules_unhide_login 14 | add path 'bpf*' unhide 15 | add path 'pf*' unhide 16 | ``` 17 | If /etc/pf.conf doesn't exist on host, it will be created from a template: 18 | ``` 19 | # Macros and tables 20 | ext_if = "EGRESS" 21 | table { 172.16.0.253 } persist 22 | table { fd10:6c79:8ae5:8b91::2 } persist 23 | 24 | # Options 25 | set block-policy drop 26 | set skip on lo0 27 | 28 | # Normalization 29 | scrub in all 30 | 31 | # NAT (comment out if adding ext_if to bridge) 32 | nat on $ext_if inet from to any -> ($ext_if) 33 | nat on $ext_if inet6 from (jails:network) to any -> ($ext_if:0) 34 | 35 | # RDR anchors, mostly for port forwarding 36 | rdr-anchor "reggae/*" on $ext_if 37 | # rdr-anchor "service/*" on $ext_if 38 | 39 | antispoof quick log for ($ext_if) # comment out if adding ext_if to bridge 40 | anchor "blacklistd/*" in on $ext_if 41 | 42 | # Rules 43 | block in log from any to (self) 44 | pass in inet proto udp to any port bootpc 45 | pass in inet6 proto udp from fe80::/10 port dhcpv6-server to fe80::/10 port dhcpv6-client 46 | pass in proto tcp to any port ssh 47 | pass in proto { icmp, igmp, icmp6 } 48 | pass out 49 | ``` 50 | 51 | DHCP jail also knows how to update PF table and DNS entries for IPs it leases, so if you use virtual machine, for example, it will be added to PF / DNS via DCHP, not hooks. 52 | 53 | You can mount extra paths by creating `template/fstab` in the service directory. For example: 54 | ``` 55 | /usr/ports /usr/ports nullfs rw 0 0 56 | ``` 57 | This example will mount /usr/ports from the host to /usr/ports inside jail. 58 | -------------------------------------------------------------------------------- /mk/ansible.mk: -------------------------------------------------------------------------------- 1 | .include <${REGGAE_PATH}/mk/common.mk> 2 | 3 | PROVISIONERS += ansible 4 | ANSIBLE != sh -c "which ansible || true" 5 | PYTHON_MAJOR = 3 6 | PYTHON_MINOR = 11 7 | 8 | provision-ansible: setup-ansible 9 | .if !exists(${CBSD_WORKDIR}/jails/${SERVICE}/usr/local/bin/python) 10 | @mdo jexec ${SERVICE} pkg install -y python 11 | .endif 12 | @mdo rm -rf ansible/site.retry 13 | @-mdo chown -R ${UID}:${GID} ~/.ansible 14 | .if exists(requirements.yml) 15 | @ansible-galaxy install -p ansible/roles -r requirements.yml 16 | .endif 17 | .if defined(server) 18 | @env ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -i ansible/inventory/inventory ansible/site.yml -b --ssh-extra-args='-J ${server}' 19 | .elif ${TYPE} == bhyve 20 | @mdo env ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook --become -i ansible/inventory/inventory ansible/site.yml 21 | .else 22 | @mdo ansible-playbook -i ansible/inventory/inventory ansible/site.yml 23 | .endif 24 | 25 | setup-ansible: 26 | @sed -e "s:SERVICE:${SERVICE}:g" ${REGGAE_PATH}/templates/ansible/group_vars/all.tpl >ansible/group_vars/all 27 | .if defined(server) 28 | @sed -e "s:SERVICE:${SERVICE}.${server}:g" ${REGGAE_PATH}/templates/ansible/inventory.remote.tpl >ansible/inventory/inventory 29 | @sed -e "s:SERVICE:${SERVICE}.${server}:g" templates/site.yml.tpl >ansible/site.yml 30 | .elif ${TYPE} == bhyve 31 | @sed -e "s:SERVICE:`mdo reggae get-ip ${SERVICE}`:g" ${REGGAE_PATH}/templates/ansible/inventory.remote.tpl >ansible/inventory/inventory 32 | @sed -e "s:SERVICE:`mdo reggae get-ip ${SERVICE}`:g" templates/site.yml.tpl >ansible/site.yml 33 | .else 34 | @sed -e "s:SERVICE:${SERVICE}:g" ${REGGAE_PATH}/templates/ansible/inventory.local.tpl >ansible/inventory/inventory 35 | @sed -e "s:SERVICE:${SERVICE}:g" templates/site.yml.tpl >ansible/site.yml 36 | .endif 37 | .if !exists(ansible/roles) 38 | @mkdir ansible/roles 39 | .endif 40 | .if ${ANSIBLE:M*} == "" 41 | @echo 42 | @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" 43 | @echo "!!! No ansible binary on the host !!!" 44 | @echo "!!! Trying to install one !!!" 45 | @echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" 46 | @echo 47 | @mdo pkg install -Uy py${PYTHON_MAJOR}${PYTHON_MINOR}-ansible 48 | .endif 49 | .if target(post_setup_ansible) 50 | @${MAKE} ${MAKEFLAGS} post_setup_ansible 51 | .endif 52 | 53 | clean-ansible: 54 | @rm -rf ansible/inventory/inventory ansible/site.yml ansible/group_vars/all 55 | -------------------------------------------------------------------------------- /templates/pkg.conf: -------------------------------------------------------------------------------- 1 | # System-wide configuration file for pkg(8) 2 | # For more information on the file format and 3 | # options please refer to the pkg.conf(5) man page 4 | 5 | # Note: you don't need to have a pkg.conf file. Many installations 6 | # will work well with no pkg.conf at all or with an empty pkg.conf 7 | # (other than comment lines). You can also override any of these 8 | # settings from the environment. 9 | 10 | # Configuration options -- default values. 11 | 12 | #PKG_DBDIR = "/var/db/pkg"; 13 | #PKG_CACHEDIR = "/var/cache/pkg"; 14 | #PORTSDIR = "/usr/ports"; 15 | #INDEXDIR = ""; 16 | #INDEXFILE = "INDEX-10"; # Autogenerated 17 | #HANDLE_RC_SCRIPTS = false; 18 | #DEFAULT_ALWAYS_YES = false; 19 | #ASSUME_ALWAYS_YES = false; 20 | #REPOS_DIR [ 21 | # "/etc/pkg/", 22 | # "/usr/local/etc/pkg/repos/", 23 | #] 24 | #PLIST_KEYWORDS_DIR = ""; 25 | #SYSLOG = true; 26 | #ABI = "freebsd:10:x86:64"; # Autogenerated 27 | #DEVELOPER_MODE = false; 28 | #VULNXML_SITE = "http://vuxml.freebsd.org/freebsd/vuln.xml.bz2"; 29 | #FETCH_RETRY = 3; 30 | PKG_PLUGINS_DIR = "/usr/local/lib/pkg/"; 31 | PKG_ENABLE_PLUGINS = true; 32 | PLUGINS [ 33 | ] 34 | #DEBUG_SCRIPTS = false; 35 | #PLUGINS_CONF_DIR = "/usr/local/etc/pkg/"; 36 | #PERMISSIVE = false; 37 | #REPO_AUTOUPDATE = true; 38 | #NAMESERVER = ""; 39 | #HTTP_USER_AGENT = "Custom_User_Manager"; 40 | #EVENT_PIPE = ""; 41 | #FETCH_TIMEOUT = 30; 42 | #UNSET_TIMESTAMP = false; 43 | #SSH_RESTRICT_DIR = ""; 44 | #PKG_ENV { 45 | #} 46 | #PKG_SSH_ARGS = ""; 47 | #DEBUG_LEVEL = 0; 48 | #ALIAS { 49 | #} 50 | #CUDF_SOLVER = ""; 51 | #SAT_SOLVER = ""; 52 | #RUN_SCRIPTS = true; 53 | #CASE_SENSITIVE_MATCH = false; 54 | #IP_VERSION = 0 55 | 56 | # Sample alias settings 57 | ALIAS : { 58 | all-depends: query %dn-%dv, 59 | annotations: info -A, 60 | build-depends: info -qd, 61 | cinfo: info -Cx, 62 | comment: query -i "%c", 63 | csearch: search -Cx, 64 | desc: query -i "%e", 65 | download: fetch, 66 | iinfo: info -ix, 67 | isearch: search -ix, 68 | prime-list: "query -e '%a = 0' '%n'", 69 | prime-origins: "query -e '%a = 0' '%o'", 70 | leaf: "query -e '%#r == 0' '%n-%v'", 71 | list: info -ql, 72 | noauto = "query -e '%a == 0' '%n-%v'", 73 | options: query -i "%n - %Ok: %Ov", 74 | origin: info -qo, 75 | provided-depends: info -qb, 76 | raw: info -R, 77 | required-depends: info -qr, 78 | roptions: rquery -i "%n - %Ok: %Ov", 79 | shared-depends: info -qB, 80 | show: info -f -k, 81 | size: info -sq, 82 | } 83 | 84 | PKG_PROXY 85 | -------------------------------------------------------------------------------- /scripts/import.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | IMAGE_PATH="${1}" 6 | 7 | if [ -z "${IMAGE_PATH}" ]; then 8 | echo "Usage: ${0} " >&2 9 | exit 1 10 | fi 11 | 12 | if [ ! -e "${IMAGE_PATH}" ]; then 13 | echo "${IMAGE_PATH} does not exist" >&2 14 | exit 1 15 | fi 16 | 17 | if [ "$(whoami)" != "root" ]; then 18 | echo "Root privileges needed" >&2 19 | exit 1 20 | fi 21 | 22 | SCRIPT_DIR=$(dirname $0) 23 | . "${SCRIPT_DIR}/utils.sh" 24 | 25 | IMAGE_ABSOLUTE_PATH="$(readlink -f "${IMAGE_PATH}")" 26 | DOMAIN=$(reggae get-config DOMAIN) 27 | PKG_PROXY=$(reggae get-config PKG_PROXY) 28 | IMAGE=$(basename "${IMAGE_PATH}") 29 | JAIL=$(echo "${IMAGE}" | sed 's;\.img$;;') 30 | FILE_TYPE=$(file -b "${IMAGE}") 31 | 32 | if [ "${FILE_TYPE}" = "data" ]; then 33 | HYPERVISOR="${2:-jail}" 34 | CBSD_WORKDIR=$(sysrc -s cbsdd -n cbsd_workdir) 35 | 36 | trap "rm -rf ${CBSD_WORKDIR}/import/${IMAGE}" HUP INT ABRT BUS TERM EXIT 37 | 38 | cp "${IMAGE_PATH}" "${CBSD_WORKDIR}/import/${IMAGE}" 39 | if [ "${HYPERVISOR}" = "jail" ]; then 40 | cbsd jimport "${JAIL}" 41 | cbsd jset jname=${JAIL} host_hostname=${JAIL}.${DOMAIN} 42 | if [ "${PKG_PROXY}" != "no" ]; then 43 | sed -i "" \ 44 | -e "s;pkg_env : { http_proxy: \".*\" };pkg_env : { http_proxy: \"http://${PKG_PROXY}\" };g" \ 45 | ${CBSD_WORKDIR}/jails-data/${JAIL}-data/usr/local/etc/pkg.conf 46 | written=$(grep -o '^pkg_env :' ${CBSD_WORKDIR}/jails-data/${JAIL}-data/usr/local/etc/pkg.conf) 47 | if [ -z "${written}" ]; then 48 | echo "pkg_env : { http_proxy: \"http://${PKG_PROXY}\" }" >>${CBSD_WORKDIR}/jails-data/${JAIL}-data/usr/local/etc/pkg.conf 49 | fi 50 | else 51 | sed -i "" \ 52 | -e "s;pkg_env : { http_proxy: \".*\" };;g" \ 53 | ${CBSD_WORKDIR}/jails-data/${JAIL}-data/usr/local/etc/pkg.conf 54 | fi 55 | else 56 | cbsd bimport "${JAIL}" 57 | fi 58 | else 59 | ID=$(next_id) 60 | CONFIG="/etc/jail.conf.d/${JAIL}.conf" 61 | USE_ZFS=$(reggae get-config USE_ZFS) 62 | ZFS_POOL=$(reggae get-config ZFS_POOL) 63 | BASE_WORKDIR=$(reggae get-config BASE_WORKDIR) 64 | 65 | check "${JAIL}" "${BASE_WORKDIR}/${JAIL}" 66 | 67 | if [ "${USE_ZFS}" = "yes" ]; then 68 | zfs create -p "${ZFS_POOL}${BASE_WORKDIR}/${JAIL}" 69 | else 70 | mkdir -p "${BASE_WORKDIR}/${JAIL}" 71 | fi 72 | tar -x -p -f "${IMAGE_PATH}" --cd "${BASE_WORKDIR}/${JAIL}" 73 | JAIL_CONFIG="$(sed -e "s/\$id = [[:digit:]]*;/\$id = ${ID};/" "${BASE_WORKDIR}/${JAIL}${CONFIG}")" 74 | echo "${JAIL_CONFIG}" >"/etc/jail.conf.d/${JAIL}.conf" 75 | rm -rf "${BASE_WORKDIR}/${JAIL}/etc/jail.conf.d" 76 | fi 77 | -------------------------------------------------------------------------------- /templates/dhcpd6.conf: -------------------------------------------------------------------------------- 1 | log-facility local7; 2 | 3 | # IPv6 address valid lifetime 4 | # (at the end the address is no longer usable by the client) 5 | # (set to 30 days, the usual IPv6 default) 6 | default-lease-time 2592000; 7 | 8 | # IPv6 address preferred lifetime 9 | # (at the end the address is deprecated, i.e., the client should use 10 | # other addresses for new connections) 11 | # (set to 7 days, the usual IPv6 default) 12 | preferred-lifetime 604800; 13 | 14 | # T1, the delay before Renew 15 | # (default is 1/2 preferred lifetime) 16 | # (set to 1 hour) 17 | option dhcp-renewal-time 3600; 18 | 19 | # T2, the delay before Rebind (if Renews failed) 20 | # (default is 3/4 preferred lifetime) 21 | # (set to 2 hours) 22 | option dhcp-rebinding-time 7200; 23 | 24 | # Enable RFC 5007 support (same than for DHCPv4) 25 | allow leasequery; 26 | 27 | # Global definitions for name server address(es) and domain search list 28 | option dhcp6.name-servers IPV6_PREFIXINTERFACE_IP6; 29 | option dhcp6.domain-search "DOMAIN"; 30 | 31 | # Set preference to 255 (maximum) in order to avoid waiting for 32 | # additional servers when there is only one 33 | ##option dhcp6.preference 255; 34 | 35 | # Server side command to enable rapid-commit (2 packet exchange) 36 | ##option dhcp6.rapid-commit; 37 | 38 | # The delay before information-request refresh 39 | # (minimum is 10 minutes, maximum one day, default is to not refresh) 40 | # (set to 6 hours) 41 | option dhcp6.info-refresh-time 21600; 42 | 43 | # The path of the lease file 44 | dhcpv6-lease-file-name "/var/db/dhcpd6.leases"; 45 | 46 | option dhcp6.next-hop code 242 = ip6-address; 47 | option dhcp6.next-hop IPV6_PREFIXINTERFACE_IP6; 48 | 49 | # The subnet where the server is attached 50 | # (i.e., the server has an address in this subnet) 51 | subnet6 IPV6_PREFIX:/64 { 52 | range6 IPV6_PREFIX:100 IPV6_PREFIXffff:ffff:ffff:fffe; 53 | on commit { 54 | set clientIP = binary-to-ascii(16, 16, ":", substring(suffix(option dhcp6.ia-na, 24), 0, 16)); 55 | set clientHost = pick-first-value(option fqdn.hostname, option host-name, ""); 56 | execute("/usr/local/bin/dhcpd-hook.sh", "ipv6", "add", clientIP, clientHost, "DOMAIN"); 57 | } 58 | on release { 59 | set clientIP = binary-to-ascii(16, 16, ":", substring(suffix(option dhcp6.ia-na, 24), 0, 16)); 60 | set clientHost = pick-first-value(option fqdn.hostname, option host-name, ""); 61 | execute("/usr/local/bin/dhcpd-hook.sh", "ipv6", "delete", clientIP, clientHost, "DOMAIN"); 62 | } 63 | on expiry { 64 | set clientIP = binary-to-ascii(16, 16, ":", substring(suffix(option dhcp6.ia-na, 24), 0, 16)); 65 | set clientHost = pick-first-value(option fqdn.hostname, option host-name, ""); 66 | execute("/usr/local/bin/dhcpd-hook.sh", "ipv6", "delete", clientIP, clientHost, "DOMAIN"); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /scripts/cbsd-init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ -f "/usr/local/etc/reggae.conf" ]; then 6 | . "/usr/local/etc/reggae.conf" 7 | fi 8 | 9 | SCRIPT_DIR=$(dirname $0) 10 | . "${SCRIPT_DIR}/default.conf" 11 | 12 | SHORT_HOSTNAME=$(hostname -s) 13 | HOSTNAME=$(hostname) 14 | NATIP=$(netstat -rn4 | awk '/^default/{print $2}' | grep '\.') 15 | EGRESS=$(netstat -rn4 | awk '/^default/{print $4}' | sort | uniq) 16 | NODEIP=$(ifconfig ${EGRESS} | awk '/inet /{print $2}' | head -n 1) 17 | TEMP_INITENV_CONF=$(mktemp) 18 | ZFSFEAT=1 19 | 20 | 21 | check() { 22 | CBSD_BIN=$(which cbsd) 23 | if [ -z "${CBSD_BIN}" ]; then 24 | echo 25 | echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" 26 | echo "!!! No cbsd binary on the host !!!" 27 | echo "!!! Trying to install one !!!" 28 | echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" 29 | echo 30 | pkg install cbsd 31 | fi 32 | } 33 | 34 | 35 | setup_file_system() { 36 | if [ ! -d "${CBSD_WORKDIR}" ]; then 37 | if [ "${USE_ZFS}" = "yes" ]; then 38 | ZFSFEAT=1 39 | zfs create -o "mountpoint=${CBSD_WORKDIR}" "${ZFS_POOL}${CBSD_WORKDIR}" 40 | else 41 | ZFSFEAT=0 42 | mkdir "${CBSD_WORKDIR}" 43 | fi 44 | fi 45 | } 46 | 47 | 48 | setup_devfs() { 49 | if [ ! -e "/etc/devfs.rules" -o -z $(grep -o 'vnet=8' /etc/devfs.rules) ]; then 50 | cat ${SCRIPT_DIR}/../templates/devfs.rules >>/etc/devfs.rules 51 | fi 52 | service devd restart 53 | service devfs restart 54 | } 55 | 56 | 57 | setup_cbsd() { 58 | RESOLVER_BASE=$(echo ${JAIL_INTERFACE_IP} | awk -F '.' '{print $1 "." $2 "." $3}') 59 | JAIL_IP_POOL="${RESOLVER_BASE}.0/24" 60 | JAIL_IP6_POOL="${IPV6_PREFIX}:/64" 61 | sed \ 62 | -e "s;HOSTNAME;${HOSTNAME};g" \ 63 | -e "s;NODEIP;${NODEIP};g" \ 64 | -e "s;NATIP;${NATIP};g" \ 65 | -e "s;JAIL_IP_POOL;${JAIL_IP_POOL};g" \ 66 | -e "s;JAIL_IP6_POOL;${JAIL_IP6_POOL};g" \ 67 | -e "s;ZFSFEAT;${ZFSFEAT};g" \ 68 | -e "s;CBSD_WORKDIR;${CBSD_WORKDIR};g" \ 69 | -e "s;INTERFACE_IP;${INTERFACE_IP};g" \ 70 | ${SCRIPT_DIR}/../templates/initenv.conf >"${TEMP_INITENV_CONF}" 71 | 72 | env workdir="${CBSD_WORKDIR}" /usr/local/cbsd/sudoexec/initenv "${TEMP_INITENV_CONF}" 73 | service cbsdd start 74 | service cbsdrsyncd start 75 | sed \ 76 | -e "s/DOMAIN/${DOMAIN}/g" \ 77 | -e "s/JAIL_INTERFACE/${INTERFACE}/g" \ 78 | "${SCRIPT_DIR}/../cbsd-profile/jail-freebsd-reggae.conf" >"${CBSD_WORKDIR}/etc/defaults/jail-freebsd-reggae.conf" 79 | rm -rf "${CBSD_WORKDIR}/share/FreeBSD-jail-reggae-skel" "${CBSD_WORKDIR}/share/jail-system-reggae" 80 | cp -r "${SCRIPT_DIR}/../cbsd-profile/skel" "${CBSD_WORKDIR}/share/FreeBSD-jail-reggae-skel" 81 | cp -r "${SCRIPT_DIR}/../cbsd-profile/system" "${CBSD_WORKDIR}/share/jail-system-reggae" 82 | chown -R root:wheel "${CBSD_WORKDIR}/share/FreeBSD-jail-reggae-skel" 83 | chown -R 666:666 "${CBSD_WORKDIR}/share/FreeBSD-jail-reggae-skel/usr/home/provision" 84 | } 85 | 86 | 87 | check 88 | setup_file_system 89 | setup_devfs 90 | setup_cbsd 91 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Reggae 2 | *REGister Globaly Access Everywhere* is a package which helps in common DevOps 3 | tasks relying on CBSD for management of jails and virtual machines on FreeBSD. 4 | If you have ever used Vagrant or Docker Compose, Reggae is best described as an 5 | alternative to those. It enables you easy development inside jail while code 6 | editing is done on the host. It makes transition from development to production 7 | easier by using provisioners. It makes host clean of all requirements of 8 | development environment and puts them inside jail which is easily stopped, 9 | started, provisioned, and destroyed. Using only `make`, `mdo` and `sh` on the 10 | system and `cbsd` from packages, makes it really small and easy to extend. 11 | 12 | ## Installation 13 | 14 | To install Reggae run the following as root: 15 | ``` 16 | pkg install reggae 17 | reggae host-init 18 | # service pflog restart 19 | # service pf restart 20 | # service sshd restart 21 | reggae backend-init 22 | reggae network-init 23 | ``` 24 | 25 | Through config file in `/usr/local/etc/reggae.conf` you can change values for 26 | anything Reggae is using. If you want to use CBSD for jail management instead 27 | of base, you should set `BACKEND=cbsd` in `reggaer.conf`. Ater 28 | `reggae network-init`, you'll get jail with DHCP and DNS which is used to lease 29 | IPs to jails and virtual machines and to register all resources in DNS so that 30 | you can use FQDN instead of IP addresses. The DNS jail IP is used in 31 | /etc/resolvconf.conf, so that changes of network parameters are passed to the 32 | appropriate jail. Also, host will use DNS jail IP in /etc/resolv.conf. In 33 | short, it enables you to not remember jail IPs when you have to use them, but 34 | use `.` to reference them, in which case comes from 35 | /usr/local/etc/reggae.conf. 36 | 37 | Or you can just 38 | **[see it all in action](https://www.youtube.com/watch?v=6GPKO6Gp7b0&list=PLtcibmaW4u3tJj8m1bKH8TbmYWxayX5VC)**, 39 | first! 40 | 41 | ## Getting started 42 | 43 | ### Service 44 | 45 | First, create empty directory for your jail/service and initialize it. 46 | ``` 47 | mkdir myservice 48 | cd myservice 49 | reggae init 50 | ``` 51 | It will create the simplest Reggae config. When you run `make`, you'll get jail 52 | named `myservice`. If you want to name it differently, change 53 | `SERVICE = myservice` line in `Makefile`. 54 | 55 | Running `make` will invoke `make up` and if it is the first time you run it, 56 | `make provision` will also be executed. 57 | 58 | Supported make targets for the service type are: 59 | * destroy 60 | * devel 61 | * exec 62 | * export 63 | * login 64 | * provision 65 | * setup 66 | * up 67 | 68 | Special note for the `devel` target: your repo must have `bin/devel.sh` which 69 | be ran inside jail. Also, devel will only work if you have `DEVEL_MODE=YES` in 70 | your vars.mk in service root. If you use it inside a project, project's 71 | `DEVEL_MODE` will be propagated. 72 | 73 | Service can be provisioned with the supported provisioners to speed up jail 74 | setup. 75 | 76 | ### Project 77 | 78 | Create empty directory and initialize it. 79 | ``` 80 | mkdir myproject 81 | cd myproject 82 | reggae project-init 83 | ``` 84 | 85 | One project can contain many services, and that's going to be shown in the 86 | generated `Makefile`. The `SERVICES` variable in it will be commented but 87 | populated with example services. All services when downloaded will be in 88 | `services/` directory. 89 | 90 | Supported make targets for the project type are: 91 | * destroy 92 | * devel 93 | * fetch 94 | * init 95 | * login service=\ 96 | * provision 97 | * setup 98 | * up 99 | 100 | Special note for the `devel` target: your repo must have `bin/devel.sh` which 101 | be ran on the host. All project targets can be suffixed with `service=` 102 | but in the above list only those which require a service are explicitely 103 | mentioned. If the service is passed as an argument, the target will be executed 104 | only on that service/jail. 105 | -------------------------------------------------------------------------------- /templates/cbsd-bhyve.freebsd.conf.tpl: -------------------------------------------------------------------------------- 1 | # DO NOT EDIT THIS FILE. PLEASE USE INSTEAD: 2 | # cbsd bconfig jname=SERVICE 3 | relative_path="1"; 4 | jname="SERVICE"; 5 | path="CBSD_WORKDIR/jails/SERVICE"; 6 | data="CBSD_WORKDIR/jails-data/SERVICE-data"; 7 | rcconf="CBSD_WORKDIR/jails-rcconf/rc.conf_SERVICE"; 8 | 9 | # FQDN for environment 10 | host_hostname="SERVICE.DOMAIN"; 11 | # default environment IP 12 | ip4_addr="172.16.0.200"; 13 | 14 | # start with system boot? 15 | astart="0"; 16 | 17 | # first NIC hardware address 18 | nic_hwaddr=""; 19 | 20 | # create from ZFS snapshot? 21 | zfs_snapsrc=""; 22 | # run immediately upon creation 23 | runasap="0"; 24 | # bind to interface 25 | interface="INTERFACE"; 26 | rctl_nice="0" 27 | # Bhyve minimal configuration: 28 | #jname="SERVICE"; 29 | # first disk size 30 | imgsize="10g"; 31 | # number of vcpu 32 | vm_cpus="1"; 33 | # ram amount 34 | vm_ram="1g"; 35 | # profile os type 36 | vm_os_type="freebsd"; 37 | # vm defaults/setting profile 38 | vm_os_profile="cloud-FreeBSD-zfs-x64-VERSION"; 39 | # end of Bhyve minimal configuration 40 | 41 | emulator="bhyve"; 42 | # disk type - md or zvol 43 | imgtype="zvol"; 44 | # efi boot? 45 | vm_efi="uefi"; 46 | # source site's for iso 47 | iso_site="https://mirror.bsdstore.ru/cloud/"; 48 | # iso image filename 49 | iso_img="FreeBSD-zfs-VERSION-RELEASE-amd64.raw"; 50 | # iso image type? 51 | iso_img_type="cloud"; 52 | # register ISO as name 53 | register_iso_name="cbsd-cloud-FreeBSD-zfs-VERSION-RELEASE-amd64.raw" 54 | # register ISO as 55 | register_iso_as="cloud-FreeBSD-zfs-x64-VERSION-RELEASE-amd64" 56 | # vm hostbridge 57 | vm_hostbridge="hostbridge"; 58 | # additional bhyve flags 59 | bhyve_flags=""; 60 | # first disk type 61 | virtio_type=""; 62 | # swap size for vm-from-jail 63 | swapsize=""; 64 | # path to iso image 65 | vm_iso_path="cloud-FreeBSD-zfs-x64-VERSION-RELEASE-amd64"; 66 | # guest fs for vm-from-jail 67 | vm_guestfs="ufs"; 68 | # VNC port 69 | vm_vnc_port="0"; 70 | # bhyve flags 71 | bhyve_generate_acpi="1"; 72 | # bhyve flags 73 | bhyve_wire_memory="0"; 74 | # bhyve flags 75 | bhyve_rts_keeps_utc="0"; 76 | # bhyve flags 77 | bhyve_force_msi_irq="0"; 78 | # bhyve flags 79 | bhyve_x2apic_mode="0"; 80 | # bhyve flags 81 | bhyve_mptable_gen="1"; 82 | # bhyve flags 83 | bhyve_ignore_msr_acc="0"; 84 | # wait for VNC connect when boot from CD 85 | cd_vnc_wait="1"; 86 | # VNC resolution 87 | bhyve_vnc_resolution="800x600"; 88 | # VNC bind addr 89 | bhyve_vnc_tcp_bind="127.0.0.1"; 90 | # vgaconf settings 91 | bhyve_vnc_vgaconf="io"; 92 | # first NIC driver 93 | nic_driver=""; 94 | # password for VNC 95 | vnc_password='cbsd'; 96 | # automatically eject CD when boot from CD and hard-disk is not empty 97 | media_auto_eject="1"; 98 | # cpu topology name 99 | vm_cpu_topology="default"; 100 | # run via debugger 101 | debug_engine="none"; 102 | # emulate xhci 103 | xhci="0"; 104 | # use alternative boot firmware 105 | cd_boot_firmware="bhyve"; 106 | # jailed bhyve ? 107 | jailed="0"; 108 | # custom behavior settings by exit codes 109 | on_poweroff="destroy"; 110 | # custom behavior settings by exit codes 111 | on_reboot="restart"; 112 | # custom behavior settings by exit codes 113 | on_crash="destroy"; 114 | # is cloud image? 115 | is_cloud='1'; 116 | # default disk sectorsize 117 | sectorsize='512/4096' 118 | # sound hardware 119 | soundhw=""; 120 | soundhw_play=""; 121 | soundhw_rec=""; 122 | # cloud-init settings 123 | ci_jname='SERVICE'; 124 | ci_fqdn='SERVICE.DOMAIN'; 125 | ci_template='centos7'; 126 | ci_interface='vtnet0'; 127 | ci_ip4_addr='DHCP'; 128 | ci_nameserver_address='MASTER_IP'; 129 | ci_nameserver_search='DOMAIN'; 130 | ci_adjust_inteface_helper='0'; 131 | ci_user_add='cbsd'; 132 | ci_user_pw_user='$6$61V0w0dRFFiEcnm2$o8CLPIdRBVHP13LQizdp12NEGD91RfHSB.c6uKnr9m2m3ZCg7ASeGENMaDt0tffmo5RalKGjWiHCtScCtjYfs/'; 133 | ci_user_pw_root='$6$h9pydrjL8JVn6vCO$9kkZInu99CT67.lnESajG4lVB.vGP6uF8otMFI.x9sYWeliDlSn7XS6GT0yTblGbO1Kb4av0ynipvXGIOCAOg1'; 134 | ci_user_gecos_provision=''; 135 | ci_user_home_cbsd='/home/cbsd'; 136 | ci_user_shell_provision=''; 137 | ci_user_member_groups_provision=''; 138 | ci_user_pubkey_provision='.ssh/authorized_keys'; 139 | -------------------------------------------------------------------------------- /mk/base-jail.mk: -------------------------------------------------------------------------------- 1 | BASE_WORKDIR != reggae get-config BASE_WORKDIR 2 | PKG_PROXY != reggae get-config PKG_PROXY 3 | DHCP ?= dhcpcd 4 | UPDATE ?= yes 5 | MKJAIL_OPTIONS = 6 | 7 | .if exists(${EXTRA_FSTAB}) 8 | MKJAIL_OPTIONS += -f ${EXTRA_FSTAB} 9 | .endif 10 | 11 | .if target(pre_up) 12 | up: setup pre_up 13 | .else 14 | up: setup 15 | .endif 16 | @echo -n "Booting ..." 17 | @mdo service jail start ${SERVICE} >/dev/null 2>&1 18 | @echo " done" 19 | .if ${DEVEL_MODE} == "YES" 20 | @mdo sysrc -s jail jail_list-="${SERVICE}" 21 | .if !exists(${BASE_WORKDIR}/${SERVICE}/home/devel) 22 | @mdo jexec ${SERVICE} pw groupadd devel -g ${GID} 23 | @mdo jexec ${SERVICE} pw useradd devel -u ${UID} -g devel -s /bin/tcsh -G wheel,operator -m 24 | @mdo jexec ${SERVICE} chpass -p '$6$MIv4IXAika7jqFH2$GkYSBax0G9CIBG0DcgQMP5gG7Qt.CojExDcU7YOQy0K.pouAd.edvo/MaQPhVO0fISxjOD4J1nzRsGVXUAxGp1' devel 25 | .endif 26 | .else 27 | @mdo sysrc -s jail jail_list+="${SERVICE}" 28 | @mdo jexec ${SERVICE} pw user del devel -r >/dev/null 2>&1 || true 29 | .endif 30 | @mdo jexec ${SERVICE} pwd_mkdb /etc/master.passwd 31 | .if target(post_up) 32 | @${MAKE} ${MAKEFLAGS} post_up 33 | .endif 34 | .if !exists(${BASE_WORKDIR}/${SERVICE}/.provisioned) 35 | @${MAKE} ${MAKEFLAGS} provision 36 | .endif 37 | 38 | provision: setup 39 | -@mdo touch ${BASE_WORKDIR}/${SERVICE}/.provisioned 40 | .for provisioner in ${PROVISIONERS} 41 | @${MAKE} ${MAKEFLAGS} provision-${provisioner} 42 | .endfor 43 | 44 | .if target(pre_down) 45 | down: setup pre_down 46 | .else 47 | down: setup 48 | .endif 49 | @mdo service jail stop ${SERVICE} 50 | .if target(post_down) 51 | @${MAKE} ${MAKEFLAGS} post_down 52 | .endif 53 | 54 | .if target(pre_destroy) 55 | destroy: pre_destroy 56 | .else 57 | destroy: 58 | .endif 59 | @mdo reggae rmjail ${SERVICE} 60 | .for provisioner in ${PROVISIONERS} 61 | @${MAKE} ${MAKEFLAGS} clean-${provisioner} 62 | .endfor 63 | .if target(post_destroy) 64 | @${MAKE} ${MAKEFLAGS} post_destroy 65 | .endif 66 | 67 | .if target(pre_setup) 68 | setup: pre_setup 69 | .else 70 | setup: 71 | .endif 72 | .for provisioner in ${PROVISIONERS} 73 | @${MAKE} ${MAKEFLAGS} setup-${provisioner} 74 | .endfor 75 | .if target(post_setup) 76 | @${MAKE} ${MAKEFLAGS} post_setup 77 | .endif 78 | .if !exists(${BASE_WORKDIR}/${SERVICE}) 79 | @mdo env PRESTART="${PRESTART}" POSTSTART="${POSTSTART}" PRESTOP="${PRESTOP}" POSTSTOP="${POSTSTOP}" OS_VERSION="${VERSION}" UPDATE="${UPDATE}" DHCP="${DHCP}" ALLOW="${ALLOW}" PORTS="${PORTS}" reggae mkjail ${MKJAIL_OPTIONS} ${SERVICE} 80 | .endif 81 | .if ${DEVEL_MODE} == "YES" 82 | -@mdo mount -t nullfs ${PWD} ${BASE_WORKDIR}/${SERVICE}/usr/src >/dev/null 2>&1 83 | .endif 84 | .if !exists(${BASE_WORKDIR}/${SERVICE}/home/provision/.ssh/authorized_keys) 85 | @mdo cp ~/.ssh/id_rsa.pub ${BASE_WORKDIR}/${SERVICE}/home/provision/.ssh/authorized_keys 86 | @mdo chmod 600 ${BASE_WORKDIR}/${SERVICE}/home/provision/.ssh/authorized_keys 87 | @mdo chown -R 666:666 ${BASE_WORKDIR}/${SERVICE}/home/provision/.ssh 88 | .endif 89 | .if target(post_create) 90 | @${MAKE} ${MAKEFLAGS} post_create 91 | .endif 92 | 93 | login: 94 | .if defined(user) 95 | @mdo jexec ${SERVICE} login -f ${user} 96 | .else 97 | @mdo jexec ${SERVICE} login -f root 98 | .endif 99 | 100 | exec: 101 | @mdo jexec ${SERVICE} ${command} 102 | 103 | .if target(pre_export) 104 | export: pre_export 105 | .else 106 | export: 107 | .if !exists(build) 108 | @mkdir build 109 | .endif 110 | @mdo reggae export ${SERVICE} build 111 | @echo "Chowning ${SERVICE}.img to ${UID}:${GID} ..." 112 | @mdo chown ${UID}:${GID} build/${SERVICE}.img 113 | .if target(post_export) 114 | @${MAKE} ${MAKEFLAGS} post_export 115 | .endif 116 | .endif 117 | 118 | devel_check: 119 | .if ${DEVEL_MODE} != "YES" 120 | @echo "DEVEL_MODE must be set to YES" 121 | @exit 1 122 | .endif 123 | 124 | .if target(do_devel) 125 | devel: devel_check up do_devel 126 | .else 127 | devel: devel_check up 128 | mdo jexec -U devel ${SERVICE} env OFFLINE=${offline} SYSPKG=${SYSPKG} /usr/src/bin/devel.sh 129 | .if target(post_devel) 130 | @${MAKE} ${MAKEFLAGS} post_devel 131 | .endif 132 | .endif 133 | 134 | .if target(do_test) 135 | test: up do_test 136 | .else 137 | test: up 138 | @mdo jexec -U devel ${SERVICE} env OFFLINE=${offline} SYSPKG=${SYSPKG} /usr/src/bin/test.sh 139 | .endif 140 | 141 | upgrade: up 142 | @mdo jexec ${SERVICE} pkg upgrade -y 143 | -------------------------------------------------------------------------------- /scripts/base-network-init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ -f "/usr/local/etc/reggae.conf" ]; then 6 | . "/usr/local/etc/reggae.conf" 7 | fi 8 | 9 | SCRIPT_DIR=$(dirname $0) 10 | . "${SCRIPT_DIR}/default.conf" 11 | 12 | SERVICE="network" 13 | 14 | setup() { 15 | if [ "${USE_IPV4}" != "yes" -a "${USE_IPV6}" != "yes" ]; then 16 | echo "IPv4 and/or IPv6 has to be enable, check USE_IPV{4,6} in config!" >&2 17 | exit 1 18 | fi 19 | if [ -z "${VER}" ]; then 20 | reggae mkjail network 21 | else 22 | env VERSION=${VER} reggae mkjail network 23 | fi 24 | echo 'sendmail_enable="NONE"' >"${BASE_WORKDIR}/${SERVICE}/etc/rc.conf.d/sendmail" 25 | if [ "${USE_IPV4}" = "yes" ]; then 26 | echo "ifconfig_eth0=\"inet ${MASTER_IP}/24\"" >>"${BASE_WORKDIR}/${SERVICE}/etc/rc.conf" 27 | echo "defaultrouter=\"${INTERFACE_IP}\"" >>"${BASE_WORKDIR}/${SERVICE}/etc/rc.conf" 28 | fi 29 | if [ "${USE_IPV6}" = "yes" ]; then 30 | echo "ifconfig_eth0_ipv6=\"inet6 ${IPV6_PREFIX}${MASTER_IP6}/64\"" >>"${BASE_WORKDIR}/${SERVICE}/etc/rc.conf" 31 | echo "ipv6_defaultrouter=\"${IPV6_PREFIX}${INTERFACE_IP6}\"" >>"${BASE_WORKDIR}/${SERVICE}/etc/rc.conf" 32 | fi 33 | pkg --chroot "${BASE_WORKDIR}/${SERVICE}" install -y isc-dhcp44-server nsd 34 | chroot "${BASE_WORKDIR}/${SERVICE}" pw group mod wheel -m dhcpd 35 | sysrc -s jail jail_list+="${SERVICE}" 36 | service jail start network 37 | } 38 | 39 | 40 | dhcp() { 41 | cp ${SCRIPT_DIR}/../templates/dhcpd-hook.sh "${BASE_WORKDIR}/${SERVICE}/usr/local/bin/" 42 | chmod 755 "${BASE_WORKDIR}/${SERVICE}/usr/local/bin/dhcpd-hook.sh" 43 | cp ${SCRIPT_DIR}/../templates/reggae-register.sh "${BASE_WORKDIR}/${SERVICE}/usr/local/bin/" 44 | chmod 755 "${BASE_WORKDIR}/${SERVICE}/usr/local/bin/reggae-register.sh" 45 | jexec ${SERVICE} pw group mod nsd -m dhcpd 46 | jexec ${SERVICE} pwd_mkdb /etc/master.passwd 47 | 48 | if [ "${USE_IPV4}" = "yes" ]; then 49 | DHCP_BASE=$(echo ${MASTER_IP} | awk -F '.' '{print $1 "." $2 "." $3}') 50 | DHCP_SUBNET_FIRST="${DHCP_BASE}.1" 51 | DHCP_SUBNET_LAST="${DHCP_BASE}.200" 52 | sed \ 53 | -e "s:DOMAIN:${DOMAIN}:g" \ 54 | -e "s:INTERFACE_IP:${INTERFACE_IP}:g" \ 55 | -e "s:MASTER_IP:${MASTER_IP}:g" \ 56 | -e "s:DHCP_SUBNET_FIRST:${DHCP_SUBNET_FIRST}:g" \ 57 | -e "s:DHCP_SUBNET_LAST:${DHCP_SUBNET_LAST}:g" \ 58 | -e "s:DHCP_BASE:${DHCP_BASE}:g" \ 59 | ${SCRIPT_DIR}/../templates/dhcpd.conf >"${BASE_WORKDIR}/${SERVICE}/usr/local/etc/dhcpd.conf" 60 | echo 'dhcpd_enable="YES"' >"${BASE_WORKDIR}/${SERVICE}/etc/rc.conf.d/dhcpd" 61 | echo 'dhcpd_flags="-q"' >>"${BASE_WORKDIR}/${SERVICE}/etc/rc.conf.d/dhcpd" 62 | echo 'dhcpd_conf="/usr/local/etc/dhcpd.conf"' >>"${BASE_WORKDIR}/${SERVICE}/etc/rc.conf.d/dhcpd" 63 | echo 'dhcpd_withumask="022"' >>"${BASE_WORKDIR}/${SERVICE}/etc/rc.conf.d/dhcpd" 64 | echo 'dhcpd_withgroup="nsd"' >>"${BASE_WORKDIR}/${SERVICE}/etc/rc.conf.d/dhcpd" 65 | jexec ${SERVICE} service isc-dhcpd start 66 | fi 67 | if [ "${USE_IPV6}" = "yes" ]; then 68 | sed \ 69 | -e "s;DOMAIN;${DOMAIN};g" \ 70 | -e "s;IPV6_PREFIX;${IPV6_PREFIX};g" \ 71 | -e "s;INTERFACE_IP6;${INTERFACE_IP6};g" \ 72 | ${SCRIPT_DIR}/../templates/dhcpd6.conf >"${BASE_WORKDIR}/${SERVICE}/usr/local/etc/dhcpd6.conf" 73 | echo 'dhcpd6_enable="YES"' >"${BASE_WORKDIR}/${SERVICE}/etc/rc.conf.d/dhcpd6" 74 | echo 'dhcpd6_withumask="022"' >>"${BASE_WORKDIR}/${SERVICE}/etc/rc.conf.d/dhcpd6" 75 | echo 'dhcpd6_withgroup="nsd"' >>"${BASE_WORKDIR}/${SERVICE}/etc/rc.conf.d/dhcpd6" 76 | touch "${BASE_WORKDIR}/${SERVICE}/var/db/dhcpd6.leases" 77 | jexec ${SERVICE} service isc-dhcpd6 start 78 | fi 79 | } 80 | 81 | 82 | dns() { 83 | echo 'nsd_enable="YES"' >"${BASE_WORKDIR}/${SERVICE}/etc/rc.conf.d/nsd" 84 | mkdir -p "${BASE_WORKDIR}/${SERVICE}/usr/local/etc/nsd/zones/master" 85 | mkdir -p "${BASE_WORKDIR}/${SERVICE}/usr/local/etc/nsd/zones/slave" 86 | sed \ 87 | -e "s:DOMAIN:${DOMAIN}:g" \ 88 | -e "s:REVERSE:${REVERSE_ZONE}:g" \ 89 | "${SCRIPT_DIR}/../templates/nsd.conf" >${BASE_WORKDIR}/${SERVICE}/usr/local/etc/nsd/nsd.conf 90 | chmod -R g+w ${BASE_WORKDIR}/${SERVICE}/usr/local/etc/nsd 91 | chown -R root:216 ${BASE_WORKDIR}/${SERVICE}/usr/local/etc/nsd 92 | 93 | jexec ${SERVICE} nsd-control-setup 94 | jexec ${SERVICE} service nsd restart 95 | if [ "${USE_IPV4}" = "yes" ]; then 96 | jexec ${SERVICE} usr/local/bin/reggae-register.sh ipv4 add ${INTERFACE_IP} @ ${DOMAIN} 97 | jexec ${SERVICE} usr/local/bin/reggae-register.sh ipv4 add ${MASTER_IP} network ${DOMAIN} 98 | fi 99 | if [ "${USE_IPV6}" = "yes" ]; then 100 | jexec ${SERVICE} usr/local/bin/reggae-register.sh ipv6 add ${IPV6_PREFIX}${MASTER_IP6} @ ${DOMAIN} 101 | jexec ${SERVICE} /usr/local/bin/reggae-register.sh ipv6 add ${IPV6_PREFIX}${MASTER_IP6} network ${DOMAIN} 102 | fi 103 | } 104 | 105 | 106 | setup 107 | dhcp 108 | dns 109 | -------------------------------------------------------------------------------- /mk/bhyve-service.mk: -------------------------------------------------------------------------------- 1 | DATA_DIR = ${CBSD_WORKDIR}/jails-data/${SERVICE}-data 2 | INTERFACE != reggae get-config INTERFACE 3 | INTERFACE_IP != reggae get-config INTERFACE_IP 4 | MASTER_IP != reggae get-config MASTER_IP 5 | PROJECTS_DIR != reggae get-config PROJECTS_DIR 6 | OS ?= "freebsd" 7 | DISTRIBUTION ?= "" 8 | VERSION ?= "native" 9 | CPU ?= 1 10 | MEM ?= "1G" 11 | 12 | .if ${VERSION} == "native" 13 | VERSION != freebsd-version | sed -e 's/-RELEASE.*//' 14 | .endif 15 | 16 | .if target(pre_up) 17 | up: ${DATA_DIR} pre_up 18 | .else 19 | up: ${DATA_DIR} 20 | .endif 21 | @mdo cbsd bset jname=${SERVICE} vm_cpus=${CPU} vm_ram=${MEM} 22 | @mdo cbsd bstart jname=${SERVICE} || true 23 | @echo "Waiting for VM to boot" 24 | @mdo reggae ssh-ping ${SERVICE} 25 | .if !exists(${CBSD_WORKDIR}/jails-system/${SERVICE}/.provisioned) 26 | @${MAKE} ${MAKEFLAGS} provision 27 | .endif 28 | .if target(post_up) 29 | @${MAKE} ${MAKEFLAGS} post_up 30 | .endif 31 | 32 | provision: 33 | -@mdo touch ${CBSD_WORKDIR}/jails-system/${SERVICE}/.provisioned 34 | .for provisioner in ${PROVISIONERS} 35 | @${MAKE} ${MAKEFLAGS} provision-${provisioner} 36 | .endfor 37 | 38 | down: 39 | @mdo cbsd bstop ${SERVICE} || true 40 | 41 | destroy: 42 | @rm -f .provisioned 43 | @mdo cbsd bremove ${SERVICE} 44 | .for provisioner in ${PROVISIONERS} 45 | @${MAKE} ${MAKEFLAGS} clean-${provisioner} 46 | .endfor 47 | 48 | ${DATA_DIR}: 49 | @sed \ 50 | -e "s:SERVICE:${SERVICE}:g" \ 51 | -e "s:DOMAIN:${DOMAIN}:g" \ 52 | -e "s:CBSD_WORKDIR:${CBSD_WORKDIR}:g" \ 53 | -e "s:MASTER_IP:${MASTER_IP}:g" \ 54 | -e "s:INTERFACE_IP:${INTERFACE_IP}:g" \ 55 | -e "s:INTERFACE:${INTERFACE}:g" \ 56 | -e "s:OS:${OS}:g" \ 57 | -e "s:DISTRIBUTION:${DISTRIBUTION}:g" \ 58 | -e "s:VERSION:${VERSION}:g" \ 59 | ${REGGAE_PATH}/templates/cbsd-bhyve.${OS}.conf.tpl >cbsd.conf 60 | @mdo cbsd bcreate jconf=${PWD}/cbsd.conf 61 | @mdo cp ${REGGAE_PATH}/templates/cloud-init/user-data ${CBSD_WORKDIR}/jails-system/${SERVICE}/cloud-init 62 | @sed \ 63 | -e "s:SERVICE:${SERVICE}:g" \ 64 | -e "s:DOMAIN:${DOMAIN}:g" \ 65 | ${REGGAE_PATH}/templates/cloud-init/meta-data >/tmp/${SERVICE}-meta-data 66 | @mdo mv /tmp/${SERVICE}-meta-data ${CBSD_WORKDIR}/jails-system/${SERVICE}/cloud-init/meta-data 67 | .for provisioner in ${PROVISIONERS} 68 | @${MAKE} ${MAKEFLAGS} setup-${provisioner} 69 | .endfor 70 | @mdo cbsd bstart jname=${SERVICE} 71 | @${MAKE} ${MAKEFLAGS} init ip=`mdo cbsd bget jname=${SERVICE} ip4_addr | cut -f 2 -d ':' | cut -b 2-` 72 | @mdo cbsd bstop ${SERVICE} 73 | 74 | init: 75 | @echo "Waiting for VM to boot for the first time" 76 | @mdo env IP=${ip} SSH_USER=cbsd reggae ssh-ping ${SERVICE} 77 | @mdo env IP=${ip} reggae scp cbsd ${SERVICE} ${REGGAE_PATH}/templates/cloud-initial.sh 78 | @mdo env IP=${ip} reggae ssh cbsd ${SERVICE} chmod +x cloud-initial.sh 79 | @mdo env IP=${ip} reggae ssh cbsd ${SERVICE} mdo ./cloud-initial.sh 80 | @mdo env IP=${ip} reggae scp cbsd ${SERVICE} ${REGGAE_PATH}/id_rsa.pub 81 | @mdo env IP=${ip} reggae ssh cbsd ${SERVICE} mdo mv /home/cbsd/id_rsa.pub /home/provision/.ssh/authorized_keys 82 | @mdo env IP=${ip} reggae ssh cbsd ${SERVICE} mdo chmod 600 /home/provision/.ssh/authorized_keys 83 | @mdo env IP=${ip} reggae ssh cbsd ${SERVICE} mdo chown -R provision:provision /home/provision 84 | @mdo env IP=${ip} reggae scp cbsd ${SERVICE} ${REGGAE_PATH}/templates/mdoers 85 | @mdo env IP=${ip} reggae ssh cbsd ${SERVICE} mdo chown root:wheel mdoers 86 | @mdo env IP=${ip} reggae ssh cbsd ${SERVICE} mdo mv mdoers /usr/local/etc/ 87 | .if defined(EXTRA_SCRIPT) 88 | @mdo env IP=${ip} reggae scp cbsd ${SERVICE} ${EXTRA_SCRIPT} 89 | @mdo env IP=${ip} reggae ssh cbsd ${SERVICE} mdo chown root:wheel `basename ${EXTRA_SCRIPT}` 90 | @mdo env IP=${ip} reggae ssh cbsd ${SERVICE} mdo chmod +x `basename ${EXTRA_SCRIPT}` 91 | @mdo env IP=${ip} reggae ssh cbsd ${SERVICE} mdo mv /home/cbsd/`basename ${EXTRA_SCRIPT}` /usr/local/bin/ 92 | .endif 93 | @mdo env IP=${ip} reggae scp provision ${SERVICE} ${REGGAE_PATH}/templates/cloud-devops.sh 94 | @mdo env IP=${ip} reggae scp provision ${SERVICE} ${REGGAE_PATH}/id_rsa.pub 95 | .if target(post_setup) 96 | @@${MAKE} ${MAKEFLAGS} post_setup ip=${ip} 97 | .endif 98 | @mdo env IP=${ip} reggae ssh provision ${SERVICE} mdo pw user del cbsd -r 99 | 100 | login: 101 | .if defined(user) 102 | @mdo env VERBOSE="yes" reggae ssh ${user} ${SERVICE} 103 | .else 104 | @mdo env VERBOSE="yes" reggae ssh provision ${SERVICE} 105 | .endif 106 | 107 | exec: 108 | @mdo env VERBOSE="yes" reggae ssh provision ${SERVICE} ${command} 109 | 110 | export: down 111 | .if !exists(build) 112 | @mkdir build 113 | .endif 114 | @mdo cbsd bexport jname=${SERVICE} 115 | @echo "Moving ${SERVICE}.img to build dir ..." 116 | @mdo mv ${CBSD_WORKDIR}/export/${SERVICE}.img build/ 117 | @echo "Chowning ${SERVICE}.img to ${UID}:${GID} ..." 118 | @mdo chown ${UID}:${GID} build/${SERVICE}.img 119 | 120 | .if target(do_devel) 121 | devel: up do_devel 122 | .else 123 | devel: up 124 | .if ${DEVEL_MODE} == "YES" 125 | @mdo reggae ssh provision ${SERVICE} mdo env UID=${UID} GID=${GID} sh cloud-devops.sh ${INTERFACE_IP} ${PWD} /usr/src ${EXTRA_SCRIPT} 126 | @mdo env VERBOSE="yes" reggae ssh devel ${SERVICE} /usr/src/bin/devel.sh 127 | .else 128 | @echo "DEVEL_MODE is not enabled" >&2 129 | @false 130 | .endif 131 | .endif 132 | 133 | test: up 134 | @mdo env VERBOSE="yes" reggae ssh devel ${SERVICE} /usr/src/bin/test.sh 135 | 136 | upgrade: up 137 | @mdo env VERBOSE="yes" reggae ssh provision ${SERVICE} pkg upgrade -y 138 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | BIN = /bin 2 | PREFIX ?= /usr/local 3 | REGGAE_DIR ?= share/reggae 4 | TEMPLATE_DIR = /${REGGAE_DIR}/templates 5 | MAKE_DIR = /${REGGAE_DIR}/mk 6 | SCRIPTS_DIR = /${REGGAE_DIR}/scripts 7 | CBSD_PROFILE_DIR = /${REGGAE_DIR}/cbsd-profile 8 | FRAMEWORKS_DIR = /${REGGAE_DIR}/mk/frameworks 9 | BIN_FILES = reggae 10 | TEMPLATES = Makefile.project \ 11 | Makefile.service \ 12 | base-jail.conf \ 13 | cbsd.conf.tpl \ 14 | cbsd-bhyve.freebsd.conf.tpl \ 15 | cbsd-vnet.conf.tpl \ 16 | cloud-devops.sh \ 17 | cloud-initial.sh \ 18 | devfs.rules \ 19 | dhcpd-hook.sh \ 20 | dhcpd.conf \ 21 | dhcpd6.conf \ 22 | export-ports.sh \ 23 | freebsd-update.conf \ 24 | gitignore \ 25 | gitignore.project \ 26 | initenv.conf \ 27 | install-packages.sh \ 28 | ip-by-mac.sh \ 29 | linux.conf.tpl \ 30 | master.conf \ 31 | master.fstab \ 32 | mount-project.sh \ 33 | netif \ 34 | network \ 35 | network-jail.conf \ 36 | nsd.conf \ 37 | pf-jail.conf \ 38 | pf.conf \ 39 | pkg.conf \ 40 | reggae-register.sh \ 41 | resolvconf.conf \ 42 | rtadvd.conf \ 43 | rtsold \ 44 | setup-vm.sh \ 45 | unbound.conf \ 46 | unbound_control.conf \ 47 | unbound_reggae.conf \ 48 | xorg.sh 49 | ANSIBLE_TEMPLATES = ansible/inventory.local.tpl ansible/inventory.remote.tpl 50 | ANSIBLE_GROUP_TEMPLATES = ansible/group_vars/all.tpl 51 | CLOUDINIT_TEMPLATES = cloud-init/meta-data \ 52 | cloud-init/user-data 53 | MAKEFILES = ansible.mk \ 54 | base-jail.mk \ 55 | bhyve-service.mk \ 56 | cbsd-jail.mk \ 57 | chef.mk \ 58 | common.mk \ 59 | frameworks/freenit.project.mk \ 60 | frameworks/freenit.service.mk \ 61 | jail-service.mk \ 62 | project.mk \ 63 | puppet.mk \ 64 | salt.mk \ 65 | service.mk \ 66 | shell.mk \ 67 | use.mk 68 | FRAMEWORKS_MAKEFILES = frameworks/freenit.project.mk \ 69 | frameworks/freenit.service.mk 70 | SCRIPTS = apply-proxy.sh \ 71 | backend-init.sh \ 72 | base-init.sh \ 73 | base-network-init.sh \ 74 | bhyve-init.sh \ 75 | cbsd-init.sh \ 76 | cbsd-network-init.sh \ 77 | chef-provision.sh \ 78 | expect-run.sh \ 79 | export.sh \ 80 | get-config.sh \ 81 | get-ip.sh \ 82 | host-init.sh \ 83 | import.sh \ 84 | init.sh \ 85 | jexec.sh \ 86 | mkjail.sh \ 87 | network-init.sh \ 88 | pf.sh \ 89 | pkg-upgrade.sh \ 90 | project-init.sh \ 91 | puppet-provision.sh \ 92 | read-pass.sh \ 93 | rmjail.sh \ 94 | salt-provision.sh \ 95 | scp.sh \ 96 | service.sh \ 97 | shell-provision.sh \ 98 | ssh-ping.sh \ 99 | ssh.sh \ 100 | start.sh \ 101 | stop.sh \ 102 | update-base.sh \ 103 | update-profiles.sh \ 104 | utils.sh \ 105 | version.sh 106 | MAN_FILES = reggae.1 107 | CBSD_PROFILE_ITEMS = skel \ 108 | system \ 109 | reggae-jail.conf 110 | 111 | 112 | all: compress_man 113 | 114 | compress_man: 115 | .for man_file in ${MAN_FILES} 116 | gzip -f -k man/${man_file} 117 | .endfor 118 | 119 | install: install_bin install_templates install_makefiles install_scripts install_man install_profile install_frameworks 120 | install -d ${DESTDIR}${PREFIX}/etc 121 | install -m 0644 reggae.conf.sample ${DESTDIR}${PREFIX}/etc 122 | install -m 0600 id_rsa id_rsa.pub ${DESTDIR}${PREFIX}/${REGGAE_DIR} 123 | install -m 0644 scripts/default.conf ${DESTDIR}${PREFIX}${SCRIPTS_DIR}/default.conf 124 | cp -r skel ${DESTDIR}${PREFIX}/${REGGAE_DIR} 125 | 126 | install_bin: 127 | install -d ${DESTDIR}${PREFIX}${BIN} 128 | .for bin_file in ${BIN_FILES} 129 | install -m 0755 bin/${bin_file} ${DESTDIR}${PREFIX}${BIN} 130 | .endfor 131 | 132 | install_templates: 133 | install -d ${DESTDIR}${PREFIX}${TEMPLATE_DIR} 134 | install -d ${DESTDIR}${PREFIX}${TEMPLATE_DIR}/ansible 135 | install -d ${DESTDIR}${PREFIX}${TEMPLATE_DIR}/ansible/group_vars 136 | install -d ${DESTDIR}${PREFIX}${TEMPLATE_DIR}/cloud-init 137 | .for template_file in ${TEMPLATES} 138 | install -m 0644 templates/${template_file} ${DESTDIR}${PREFIX}${TEMPLATE_DIR} 139 | .endfor 140 | .for template_file in ${ANSIBLE_TEMPLATES} 141 | install -m 0644 templates/${template_file} ${DESTDIR}${PREFIX}${TEMPLATE_DIR}/ansible 142 | .endfor 143 | .for template_file in ${ANSIBLE_GROUP_TEMPLATES} 144 | install -m 0644 templates/${template_file} ${DESTDIR}${PREFIX}${TEMPLATE_DIR}/ansible/group_vars 145 | .endfor 146 | .for template_file in ${CLOUDINIT_TEMPLATES} 147 | install -m 0644 templates/${template_file} ${DESTDIR}${PREFIX}${TEMPLATE_DIR}/cloud-init 148 | .endfor 149 | 150 | install_makefiles: 151 | install -d ${DESTDIR}${PREFIX}${MAKE_DIR} 152 | .for make_file in ${MAKEFILES} 153 | install -m 0644 mk/${make_file} ${DESTDIR}${PREFIX}${MAKE_DIR} 154 | .endfor 155 | 156 | install_scripts: 157 | install -d ${DESTDIR}${PREFIX}${SCRIPTS_DIR} 158 | .for script_file in ${SCRIPTS} 159 | install -m 0755 scripts/${script_file} ${DESTDIR}${PREFIX}${SCRIPTS_DIR} 160 | .endfor 161 | 162 | install_man: 163 | install -d ${DESTDIR}${PREFIX}/share/man/man1 164 | .for man_file in ${MAN_FILES} 165 | install -m 0644 man/${man_file}.gz ${DESTDIR}${PREFIX}/share/man/man1 166 | .endfor 167 | 168 | install_profile: 169 | install -d ${DESTDIR}${PREFIX}${CBSD_PROFILE_DIR} 170 | cp -r cbsd-profile/* ${DESTDIR}${PREFIX}${CBSD_PROFILE_DIR}/ 171 | 172 | install_frameworks: 173 | install -d ${DESTDIR}${PREFIX}${FRAMEWORKS_DIR} 174 | .for framework_file in ${FRAMEWORKS_MAKEFILES} 175 | install -m 0644 mk/${framework_file} ${DESTDIR}${PREFIX}${FRAMEWORKS_DIR} 176 | .endfor 177 | 178 | clean: 179 | rm man/*.gz 180 | -------------------------------------------------------------------------------- /mk/project.mk: -------------------------------------------------------------------------------- 1 | .if exists(vars.mk) 2 | .include 3 | .endif 4 | 5 | DEVEL_MODE ?= "NO" 6 | RUNNING_UID := `id -u` 7 | RUNNING_GID := `id -g` 8 | UID ?= ${RUNNING_UID} 9 | GID ?= ${RUNNING_GID} 10 | VERSION ?= "native" 11 | USE_FREENIT ?= NO 12 | 13 | .if ${USE_FREENIT} == "YES" 14 | .include <${REGGAE_PATH}/mk/frameworks/freenit.project.mk> 15 | .endif 16 | .include <${REGGAE_PATH}/mk/use.mk> 17 | 18 | dependencies := NO 19 | 20 | .MAIN: up 21 | 22 | .if target(pre_up) 23 | up: fetch setup pre_up 24 | .else 25 | up: fetch setup 26 | .endif 27 | .if defined(service) 28 | @echo "=== ${service} ===" 29 | @${MAKE} ${MAKEFLAGS} -C services/${service} up 30 | .else 31 | .for service url in ${ALL_SERVICES} 32 | @echo "=== ${service} ===" 33 | @${MAKE} ${MAKEFLAGS} -C services/${service} up 34 | .endfor 35 | .endif 36 | 37 | provision: 38 | .if defined(service) 39 | @echo "=== ${service} ===" 40 | @${MAKE} ${MAKEFLAGS} -C services/${service} provision 41 | .else 42 | .for service url in ${ALL_SERVICES} 43 | @echo "=== ${service} ===" 44 | @${MAKE} ${MAKEFLAGS} -C services/${service} provision 45 | .endfor 46 | .endif 47 | 48 | init: 49 | .if !exists(services) 50 | @mkdir services 51 | .endif 52 | 53 | fetch: 54 | .for service url in ${ALL_SERVICES} 55 | .if !exists(services/${service}) 56 | @git clone ${url} services/${service} 57 | .endif 58 | .endfor 59 | .for repo url in ${EXTRA_REPOS} 60 | .if !exists(repos/${repo}) 61 | @git clone ${url} repos/${repo} 62 | .endif 63 | .endfor 64 | 65 | .if target(pre_setup) 66 | setup: pre_setup 67 | .else 68 | setup: 69 | .endif 70 | @mdo rm -f services/*/cbsd.conf 71 | .for service url in ${ALL_SERVICES} 72 | @rm -f services/${service}/project.mk 73 | @echo "DEVEL_MODE ?= ${DEVEL_MODE}" >>services/${service}/project.mk 74 | @echo "GID ?= ${GID}" >>services/${service}/project.mk 75 | @echo "UID ?= ${UID}" >>services/${service}/project.mk 76 | @echo "VERSION ?= ${VERSION}" >>services/${service}/project.mk 77 | .endfor 78 | .if target(post_setup) 79 | @${MAKE} ${MAKEFLAGS} post_setup 80 | .endif 81 | 82 | devel_check: 83 | .if ${DEVEL_MODE} != "YES" 84 | @echo "DEVEL_MODE must be set to YES" 85 | @exit 1 86 | .endif 87 | 88 | .if target(do_devel) 89 | devel: devel_check up do_devel 90 | .else 91 | devel: devel_check up 92 | .if defined(service) 93 | @${MAKE} ${MAKEFLAGS} -C services/${service} devel offline=${offline} 94 | .else 95 | @env OFFLINE=${offline} REGGAE=yes bin/devel.sh `make service_names` 96 | .endif 97 | .endif 98 | 99 | test: up 100 | .if defined(service) 101 | @${MAKE} ${MAKEFLAGS} -C services/${service} OFFLINE=${offline} test 102 | .else 103 | .for service url in ${SERVICES} 104 | @${MAKE} ${MAKEFLAGS} -C services/${service} OFFLINE=${offline} test 105 | .endfor 106 | .endif 107 | 108 | destroy: 109 | .if defined(service) 110 | @${MAKE} ${MAKEFLAGS} -C services/${service} destroy 111 | .else 112 | .if ${dependencies} == "yes" 113 | .for url service in ${POST_SERVICES:[-1..1]} 114 | @${MAKE} ${MAKEFLAGS} -C services/${service} destroy 115 | .endfor 116 | .endif 117 | .for url service in ${SERVICES:[-1..1]} 118 | @${MAKE} ${MAKEFLAGS} -C services/${service} destroy 119 | .endfor 120 | .if ${dependencies} == "yes" 121 | .for url service in ${USED_SERVICES:[-1..1]} 122 | @${MAKE} ${MAKEFLAGS} -C services/${service} destroy 123 | .endfor 124 | .for url service in ${PRE_SERVICES:[-1..1]} 125 | @${MAKE} ${MAKEFLAGS} -C services/${service} destroy 126 | .endfor 127 | .endif 128 | .endif 129 | 130 | login: 131 | .if defined(service) 132 | @${MAKE} ${MAKEFLAGS} -C services/${service} login 133 | .else 134 | @mdo cbsd jlogin 135 | .endif 136 | 137 | down: setup 138 | .if defined(service) 139 | @${MAKE} ${MAKEFLAGS} -C services/${service} down 140 | .else 141 | .if ${dependencies} == "yes" 142 | .for url service in ${POST_SERVICES:[-1..1]} 143 | @${MAKE} ${MAKEFLAGS} -C services/${service} down 144 | .endfor 145 | .endif 146 | .for url service in ${SERVICES:[-1..1]} 147 | @${MAKE} ${MAKEFLAGS} -C services/${service} down 148 | .endfor 149 | .if ${dependencies} == "yes" 150 | .for url service in ${USED_SERVICES:[-1..1]} 151 | @${MAKE} ${MAKEFLAGS} -C services/${service} down 152 | .endfor 153 | .for url service in ${PRE_SERVICES:[-1..1]} 154 | @${MAKE} ${MAKEFLAGS} -C services/${service} down 155 | .endfor 156 | .endif 157 | .endif 158 | 159 | export: 160 | .if defined(service) 161 | @echo "exporting ${service}" 162 | @${MAKE} ${MAKEFLAGS} -C services/${service} export 163 | .else 164 | .if ${dependencies} == "yes" 165 | .for service url in ${ALL_SERVICES} 166 | @echo "exporting ${service}" 167 | @${MAKE} ${MAKEFLAGS} -C services/${service} export 168 | .endfor 169 | .else 170 | .for service url in ${SERVICES} 171 | @echo "exporting ${service}" 172 | @${MAKE} ${MAKEFLAGS} -C services/${service} export 173 | .endfor 174 | .endif 175 | .endif 176 | 177 | update: fetch 178 | @git pull 179 | .if ${dependencies} == "yes" 180 | .for service url in ${ALL_SERVICES} 181 | @echo "=== ${service} ===" 182 | @${MAKE} ${MAKEFLAGS} -C services/${service} update 183 | .endfor 184 | .else 185 | .for service url in ${SERVICES} 186 | @echo "=== ${service} ===" 187 | @${MAKE} ${MAKEFLAGS} -C services/${service} update 188 | .endfor 189 | .endif 190 | 191 | upgrade: 192 | .for service url in ${SERVICES} 193 | @echo "=== ${service} ===" 194 | @${MAKE} ${MAKEFLAGS} -C services/${service} upgrade 195 | .endfor 196 | 197 | print_services: 198 | .if ${dependencies} == "yes" 199 | @echo ${ALL_SERVICES} 200 | .else 201 | @echo ${SERVICES} 202 | .endif 203 | 204 | service_names: 205 | .if ${dependencies} == "yes" 206 | .for service url in ${ALL_SERVICES} 207 | @echo ${service} 208 | .endfor 209 | .else 210 | .for service url in ${SERVICES} 211 | @echo ${service} 212 | .endfor 213 | .endif 214 | 215 | service_urls: 216 | .if ${dependencies} == "yes" 217 | .for service url in ${ALL_SERVICES} 218 | @echo ${url} 219 | .endfor 220 | .else 221 | .for service url in ${SERVICES} 222 | @echo ${url} 223 | .endfor 224 | .endif 225 | 226 | .if ${dependencies} == "yes" 227 | restart: 228 | @${MAKE} ${MAKEFLAGS} down dependencies=yes 229 | @${MAKE} ${MAKEFLAGS} up 230 | .else 231 | restart: down up 232 | .endif 233 | -------------------------------------------------------------------------------- /scripts/host-init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ -f "/usr/local/etc/reggae.conf" ]; then 6 | . "/usr/local/etc/reggae.conf" 7 | fi 8 | 9 | SCRIPT_DIR=$(dirname $0) 10 | . "${SCRIPT_DIR}/default.conf" 11 | . "${SCRIPT_DIR}/../templates/reggae-register.sh" 12 | 13 | SHORT_HOSTNAME=$(hostname -s) 14 | HOSTNAME=$(hostname) 15 | CLONED_INTERFACES=$(sysrc -n cloned_interfaces) 16 | NATIP=$(netstat -rn4 | awk '/^default/{print $2}') 17 | EGRESS=$(netstat -rn4 | awk '/^default/{print $4}') 18 | EGRESS_CONFIG=$(sysrc -n ifconfig_${EGRESS} 2>/dev/null) 19 | DHCP_CONFIG=$(echo ${EGRESS_CONFIG} | grep -io dhcp) 20 | STATIC=NO 21 | NETWORK=$(echo ${MASTER_IP} | awk -F '.' '{print $1 "." $2 "." $3 ".0/24"}') 22 | 23 | 24 | if [ -z "${DHCP_CONFIG}" ]; then 25 | STATIC=YES 26 | fi 27 | 28 | 29 | check_config() { 30 | if [ -z "${PROJECTS_DIR}" ]; then 31 | echo "PROJECTS_DIR must be set in /usr/local/etc/reggae.conf" >&2 32 | exit 1 33 | fi 34 | if [ $(hostname) = $(hostname -s) ]; then 35 | echo "Hostname must be FQDN. Please set hostname to something like 'myhost.example.com'" >&2 36 | exit 1 37 | fi 38 | } 39 | 40 | 41 | setup_mdo() { 42 | EXISTING="$(egrep -o '^security.mac.do.rules=' /etc/sysctl.conf)" 43 | if [ -z "${EXISTING}" ]; then 44 | kldload mac_do 45 | sysctl "security.mac.do.rules=gid=0:any" 46 | echo "security.mac.do.rules=gid=0:any" >>/etc/sysctl.conf 47 | fi 48 | sysrc kld_list+="mac_do" 49 | } 50 | 51 | 52 | setup_network() { 53 | interface_config="inet ${INTERFACE_IP} netmask 255.255.255.0" 54 | interface_ipv6_config="inet6 -ifdisabled auto_linklocal ${IPV6_PREFIX}${INTERFACE_IP6}" 55 | 56 | BRIDGE_MEMBERS_CONFIG="" 57 | for member in ${BRIDGE_MEMBERS}; do 58 | BRIDGE_MEMBERS_CONFIG="${BRIDGE_MEMBERS_CONFIG} addm ${member}" 59 | done 60 | if [ ! -z "${BRIDGE_MEMBERS_CONFIG}" ]; then 61 | interface_config="${interface_config}${BRIDGE_MEMBERS_CONFIG}" 62 | fi 63 | 64 | sysrc cloned_interfaces+="bridge0" 65 | sysrc ifconfig_bridge0_name="${INTERFACE}" 66 | if [ "${USE_IPV4}" = "yes" ]; then 67 | sysctl net.inet.ip.forwarding=1 68 | sysrc gateway_enable="YES" 69 | sysrc ifconfig_${INTERFACE}="${interface_config}" 70 | sysrc ifconfig_${INTERFACE}_alias0="${interface_alias_config}" 71 | fi 72 | if [ "${USE_IPV6}" = "yes" ]; then 73 | sysrc ipv6_gateway_enable="YES" 74 | sysctl net.inet6.ip6.forwarding=1 75 | sysrc ifconfig_${INTERFACE}_ipv6="${interface_ipv6_config}" 76 | fi 77 | 78 | service netif cloneup 79 | sleep 1 80 | 81 | if [ "${USE_IPV4}" = "yes" ]; then 82 | ifconfig ${INTERFACE} ${interface_config} 83 | ifconfig ${INTERFACE} ${interface_alias_config} alias 84 | fi 85 | if [ "${USE_IPV6}" = "yes" ]; then 86 | ifconfig ${INTERFACE} ${interface_ipv6_config} 87 | fi 88 | } 89 | 90 | 91 | setup_pf() { 92 | if [ ! -e /etc/pf.conf ]; then 93 | sed \ 94 | -e "s;EGRESS;${EGRESS};g" \ 95 | -e "s;IPV6_PREFIX;${IPV6_PREFIX};g" \ 96 | -e "s;MASTER_IP6;${MASTER_IP6};g" \ 97 | -e "s;INTERFACE;${INTERFACE};g" \ 98 | -e "s;MASTER_IP;${MASTER_IP};g" \ 99 | "${SCRIPT_DIR}/../templates/pf.conf" >/etc/pf.conf 100 | fi 101 | service pflog enable 102 | service pf enable 103 | service blacklistd enable 104 | sysrc sshd_flags+="\-oUseBlacklist=yes" 105 | } 106 | 107 | 108 | setup_hostname() { 109 | if [ "${HOSTNAME}" == "${SHORT_HOSTNAME}" ]; then 110 | HOSTNAME="${SHORT_HOSTNAME}.${DOMAIN}" 111 | hostname ${HOSTNAME} 112 | sysrc hostname="${HOSTNAME}" 113 | fi 114 | } 115 | 116 | 117 | setup_rtadvd() { 118 | if [ "${USE_IPV6}" = "yes" ]; then 119 | sysrc rtadvd_enable="YES" 120 | sysrc rtadvd_interfaces="${INTERFACE}" 121 | sed \ 122 | -e "s;INTERFACE;${INTERFACE};g" \ 123 | -e "s;IPV6_PREFIX;${IPV6_PREFIX};g" \ 124 | "${SCRIPT_DIR}/../templates/rtadvd.conf" >/etc/rtadvd.conf 125 | fi 126 | } 127 | 128 | 129 | setup_nfs() { 130 | TMP_EXPORTS=$(mktemp) 131 | sysrc mountd_enable="YES" 132 | sysrc mountd_flags="-r" 133 | sysrc nfs_server_enable="YES" 134 | sysrc nfsv4_server_enable="YES" 135 | sysrc rpcbind_enable="YES" 136 | 137 | if [ -e /etc/exports ]; then 138 | egrep -v '^V4:' /etc/exports >"${TMP_EXPORTS}" 139 | fi 140 | echo "${PROJECTS_DIR} -alldirs -network ${INTERFACE_IP} -mask 255.255.255.0" -maproot=root >>"${TMP_EXPORTS}" 141 | sort "${TMP_EXPORTS}" | uniq > /etc/exports 142 | echo "V4: /" >>/etc/exports 143 | 144 | service rpcbind restart 145 | service nfsd restart 146 | service mountd restart 147 | rm "${TMP_EXPORTS}" 148 | } 149 | 150 | 151 | setup_unbound() { 152 | REVERSE_ZONE=$(get_zone ipv4 ${INTERFACE_IP}) 153 | REVERSEV6=$(get_zone ipv6 ${IPV6_PREFIX}${MASTER_IP6}) 154 | 155 | service local_unbound enable 156 | sysrc local_unbound_tls="NO" 157 | sysrc local_unbound_svcj="YES" 158 | fetch -o /var/unbound/root.hints https://www.internic.net/domain/named.cache 159 | resolvconf -u 160 | service local_unbound restart 161 | sed \ 162 | -e "s;IPV6_PREFIX;${IPV6_PREFIX};g" \ 163 | -e "s;INTERFACE_IP6;${INTERFACE_IP6};g" \ 164 | -e "s;INTERFACE_IP;${INTERFACE_IP};g" \ 165 | "${SCRIPT_DIR}/../templates/unbound.conf" >/var/unbound/unbound.conf 166 | sed \ 167 | -e "s;DOMAIN;${DOMAIN};g" \ 168 | -e "s;IPV6_PREFIX;${IPV6_PREFIX};g" \ 169 | -e "s;MASTER_IP6;${MASTER_IP6};g" \ 170 | -e "s;REVERSEV6;${REVERSEV6};g" \ 171 | -e "s;REVERSE;${REVERSE_ZONE};g" \ 172 | -e "s;MASTER_IP;${MASTER_IP};g" \ 173 | "${SCRIPT_DIR}/../templates/unbound_reggae.conf" >/var/unbound/reggae.conf 174 | cp "${SCRIPT_DIR}/../templates/unbound_control.conf" /var/unbound/control.conf 175 | cp "${SCRIPT_DIR}/../templates/resolvconf.conf" /etc/resolvconf.conf 176 | 177 | if [ ! -d /var/unbound/conf.d ]; then 178 | mkdir /var/unbound/conf.d 179 | fi 180 | if [ ! -d /var/unbound/zones ]; then 181 | mkdir /var/unbound/zones 182 | fi 183 | chown -R unbound:unbound /var/unbound 184 | service local_unbound restart 185 | resolvconf -u 186 | } 187 | 188 | 189 | check_config 190 | setup_mdo 191 | setup_network 192 | setup_pf 193 | setup_hostname 194 | setup_rtadvd 195 | setup_nfs 196 | setup_unbound 197 | -------------------------------------------------------------------------------- /scripts/cbsd-network-init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ -f "/usr/local/etc/reggae.conf" ]; then 6 | . "/usr/local/etc/reggae.conf" 7 | fi 8 | 9 | SCRIPT_DIR=$(dirname $0) 10 | . "${SCRIPT_DIR}/default.conf" 11 | 12 | HOSTNAME=$(hostname) 13 | EGRESS=$(netstat -rn4 | awk '/^default/{print $4}') 14 | EGRESS_CONFIG=$(sysrc -n ifconfig_${EGRESS}) 15 | DHCP_CONFIG=$(echo ${EGRESS_CONFIG} | grep -io dhcp) 16 | NODEIP=$(ifconfig ${EGRESS} | awk '/inet /{print $2}') 17 | TEMP_MASTER_CONF=$(mktemp) 18 | TEMP_DHCP_CONF=$(mktemp) 19 | export VER=${VER:="native"} 20 | SERVICE="network" 21 | export ARCH=${ARCH:="$(uname -m)"} 22 | export TARGET_ARCH=${TARGET_ARCH:="$(uname -p)"} 23 | 24 | setup() { 25 | if [ "${USE_IPV4}" != "yes" -a "${USE_IPV6}" != "yes" ]; then 26 | echo "IPv4 and/or IPv6 has to be enable, check USE_IPV{4,6} in config!" >&2 27 | exit 1 28 | fi 29 | 30 | if [ -z "${VER}" -o "${VER}" = "native" ]; then 31 | tmpver=$( uname -r ) 32 | VER=${tmpver%%-*} 33 | unset tmpver 34 | fi 35 | # or check for /bin/sh via: [ ! -x ${CBSD_WORKDIR}/basejail/base_${ARCH}_${TARGET_ARCH}_${VER}/bin/sh" ] - whats about linux jail without /bin/sh ? 36 | if [ ! -d "${CBSD_WORKDIR}/basejail/base_${ARCH}_${TARGET_ARCH}_${VER}/bin" ]; then 37 | echo "no such bases: base_${ARCH}_${TARGET_ARCH}_${VER}/bin, fetch via 'cbsd repo'" 38 | cbsd repo action=get sources=base ver=${VER} 39 | # extra check for "${CBSD_WORKDIR}/basejail/base_${ARCH}_${TARGET_ARCH}_${VER}/bin" directory ? 40 | fi 41 | 42 | env NOINTER=1 cbsd jcreate jname=network host_hostname=network.${DOMAIN} runasap=0 vnet=1 b_order=0 devfs_ruleset=8 ip4_addr=${MASTER_IP},${IPV6_PREFIX}${MASTER_IP6} ci_gw4=${INTERFACE_IP},${IPV6_PREFIX}${INTERFACE_IP6} interface=${INTERFACE} 43 | mkdir -p "${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/etc/pkg/repos" 44 | echo -e "FreeBSD: {\n url: \"pkg+http://${PKG_MIRROR}/\${ABI}/${PKG_REPO}\",\n}">"${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/etc/pkg/repos/FreeBSD.conf" 45 | echo 'sendmail_enable="NONE"' >"${CBSD_WORKDIR}/jails-data/${SERVICE}-data/etc/rc.conf.d/sendmail" 46 | cp ${SCRIPT_DIR}/../templates/master.fstab "${CBSD_WORKDIR}/jails-fstab/${SERVICE}/fstab.local" 47 | echo "#!/bin/sh" >"${CBSD_WORKDIR}/jails-system/network/master_poststart.d/reggae.sh" 48 | echo "service reggae onerestart" >>"${CBSD_WORKDIR}/jails-system/network/master_poststart.d/reggae.sh" 49 | echo "service reggae_pf onerestart" >>"${CBSD_WORKDIR}/jails-system/network/master_poststart.d/reggae.sh" 50 | chmod +x "${CBSD_WORKDIR}/jails-system/network/master_poststart.d/reggae.sh" 51 | mkdir /var/run/reggae &>/dev/null 52 | cbsd jstart ${SERVICE} 53 | cbsd jexec jname=${SERVICE} cmd="env ASSUME_ALWAYS_YES=YES pkg bootstrap -f" 54 | cbsd jexec jname=${SERVICE} cmd="pkg install -y isc-dhcp44-server nsd" 55 | chroot "${BASE_WORKDIR}/${SERVICE}" pw group mod wheel -m dhcpd 56 | } 57 | 58 | 59 | dhcp() { 60 | cp ${SCRIPT_DIR}/../templates/dhcpd-hook.sh "${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/bin/" 61 | chmod 755 "${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/bin/dhcpd-hook.sh" 62 | cp ${SCRIPT_DIR}/../templates/reggae-register.sh "${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/bin/" 63 | chmod 755 "${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/bin/reggae-register.sh" 64 | DHCP_BASE=$(echo ${MASTER_IP} | awk -F '.' '{print $1 "." $2 "." $3}') 65 | DHCP_SUBNET_FIRST="${DHCP_BASE}.1" 66 | DHCP_SUBNET_LAST="${DHCP_BASE}.200" 67 | if [ "${USE_IPV4}" = "yes" ]; then 68 | sed \ 69 | -e "s:DOMAIN:${DOMAIN}:g" \ 70 | -e "s:INTERFACE_IP:${INTERFACE_IP}:g" \ 71 | -e "s:MASTER_IP:${MASTER_IP}:g" \ 72 | -e "s:DHCP_SUBNET_FIRST:${DHCP_SUBNET_FIRST}:g" \ 73 | -e "s:DHCP_SUBNET_LAST:${DHCP_SUBNET_LAST}:g" \ 74 | -e "s:DHCP_BASE:${DHCP_BASE}:g" \ 75 | ${SCRIPT_DIR}/../templates/dhcpd.conf >"${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/etc/dhcpd.conf" 76 | echo 'dhcpd_enable="YES"' >"${CBSD_WORKDIR}/jails-data/${SERVICE}-data/etc/rc.conf.d/dhcpd" 77 | echo 'dhcpd_flags="-q"' >>"${CBSD_WORKDIR}/jails-data/${SERVICE}-data/etc/rc.conf.d/dhcpd" 78 | echo 'dhcpd_conf="/usr/local/etc/dhcpd.conf"' >>"${CBSD_WORKDIR}/jails-data/${SERVICE}-data/etc/rc.conf.d/dhcpd" 79 | echo 'dhcpd_withumask="022"' >>"${CBSD_WORKDIR}/jails-data/${SERVICE}-data/etc/rc.conf.d/dhcpd" 80 | echo 'dhcpd_withgroup="nsd"' >>"${CBSD_WORKDIR}/jails-data/${SERVICE}-data/etc/rc.conf.d/dhcpd" 81 | fi 82 | if [ "${USE_IPV6}" = "yes" ]; then 83 | sed \ 84 | -e "s;DOMAIN;${DOMAIN};g" \ 85 | -e "s;IPV6_PREFIX;${IPV6_PREFIX};g" \ 86 | -e "s;INTERFACE_IP6;${INTERFACE_IP6};g" \ 87 | ${SCRIPT_DIR}/../templates/dhcpd6.conf >"${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/etc/dhcpd6.conf" 88 | echo 'dhcpd6_enable="YES"' >"${CBSD_WORKDIR}/jails-data/${SERVICE}-data/etc/rc.conf.d/dhcpd6" 89 | echo 'dhcpd6_withumask="022"' >>"${CBSD_WORKDIR}/jails-data/${SERVICE}-data/etc/rc.conf.d/dhcpd6" 90 | echo 'dhcpd6_withgroup="nsd"' >>"${CBSD_WORKDIR}/jails-data/${SERVICE}-data/etc/rc.conf.d/dhcpd6" 91 | touch "${CBSD_WORKDIR}/jails-data/${SERVICE}-data/var/db/dhcpd6.leases" 92 | fi 93 | sed \ 94 | -e "s:MASTER_IP:${MASTER_IP}:g" \ 95 | ${SCRIPT_DIR}/../templates/ip-by-mac.sh >"${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/bin/ip-by-mac.sh" 96 | chmod 755 "${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/bin/ip-by-mac.sh" 97 | 98 | cbsd jexec jname=${SERVICE} cmd="pw group mod nsd -m dhcpd" 99 | cbsd jexec jname=${SERVICE} cmd="pwd_mkdb /etc/master.passwd" 100 | cbsd jexec jname=${SERVICE} cmd="service isc-dhcpd restart" 101 | if [ "${USE_IPV6}" = "yes" ]; then 102 | cbsd jexec jname=${SERVICE} cmd="service isc-dhcpd6 restart" 103 | fi 104 | } 105 | 106 | 107 | dns() { 108 | echo 'nsd_enable="YES"' >"${CBSD_WORKDIR}/jails-data/${SERVICE}-data/etc/rc.conf.d/nsd" 109 | mkdir -p "${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/etc/nsd/zones/master" 110 | mkdir -p "${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/etc/nsd/zones/slave" 111 | sed \ 112 | -e "s:DOMAIN:${DOMAIN}:g" \ 113 | -e "s:REVERSE:${REVERSE_ZONE}:g" \ 114 | "${SCRIPT_DIR}/../templates/nsd.conf" >${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/etc/nsd/nsd.conf 115 | 116 | chmod -R g+w ${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/etc/nsd 117 | chown -R root:216 ${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/etc/nsd 118 | cbsd jexec jname=${SERVICE} cmd="nsd-control-setup" 119 | cbsd jexec jname=${SERVICE} cmd="service nsd restart" 120 | if [ "${USE_IPV4}" = "yes" ]; then 121 | cbsd jexec jname=${SERVICE} cmd="/usr/local/bin/reggae-register.sh ipv4 add ${INTERFACE_IP} @ ${DOMAIN}" 122 | cbsd jexec jname=${SERVICE} cmd="/usr/local/bin/reggae-register.sh ipv4 add ${MASTER_IP} network ${DOMAIN}" 123 | fi 124 | if [ "${USE_IPV6}" = "yes" ]; then 125 | cbsd jexec jname=${SERVICE} cmd="/usr/local/bin/reggae-register.sh ipv6 add ${IPV6_PREFIX}${MASTER_IP6} @ ${DOMAIN}" 126 | cbsd jexec jname=${SERVICE} cmd="/usr/local/bin/reggae-register.sh ipv6 add ${IPV6_PREFIX}${MASTER_IP6} network ${DOMAIN}" 127 | fi 128 | } 129 | 130 | 131 | setup 132 | dhcp 133 | dns 134 | -------------------------------------------------------------------------------- /templates/reggae-register.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | 4 | SOCKET=${SOCKET:="/var/run/reggae/reggae.sock"} 5 | ZONE_ROOT=${ZONE_ROOT:="/usr/local/etc/nsd/zones/master"} 6 | 7 | 8 | expand_address() { 9 | ip=$1 10 | double_color_exists=`echo ${ip} | grep -o '::'` 11 | if [ -z "${double_color_exists}" ]; then 12 | echo "${ip}" 13 | return 14 | fi 15 | part_number=`echo "${ip}" | sed 's/:/ /g' | wc -w | xargs` 16 | zero_number=`echo "8 - ${part_number}" | bc` 17 | double_colon_removed=`echo "${ip}" | sed 's/::/ /g'` 18 | first_part=`echo "${double_colon_removed}" | cut -f 1 -d ' '` 19 | last_part=`echo "${double_colon_removed}" | cut -f 2 -d ' '` 20 | address="" 21 | for part in $(echo "${first_part}" | sed 's/:/ /g'); do 22 | address="${address}:${part}" 23 | done 24 | 25 | if [ "${zero_number}" != "0" ]; then 26 | for zeros in $(seq 1 ${zero_number}); do 27 | address="${address}:0000" 28 | done 29 | fi 30 | 31 | for part in $(echo "${last_part}" | sed 's/:/ /g'); do 32 | address="${address}:${part}" 33 | done 34 | echo $address | cut -b 2- 35 | } 36 | 37 | 38 | reverse_address() { 39 | rev_address="" 40 | address=$1 41 | for part in $(echo "${address}" | sed 's/:/ /g'); do 42 | part_length=`echo "${part}" | wc -c | xargs` 43 | zero_length=`echo "5 - ${part_length}" | bc` 44 | if [ "${zero_length}" != "0" ]; then 45 | for zero in $(seq 1 ${zero_length}); do 46 | rev_address="${rev_address}0" 47 | done 48 | fi 49 | rev_address="${rev_address}${part}" 50 | done 51 | echo "${rev_address}" | rev 52 | } 53 | 54 | 55 | get_zone() { 56 | INET="${1}" 57 | IP="${2}" 58 | if [ "${INET}" = "ipv4" ]; then 59 | echo ${IP} | /usr/bin/awk -F '.' '{print $3 "." $2 "." $1 ".in-addr.arpa"}' 60 | elif [ "${INET}" = "ipv6" ]; then 61 | zone="" 62 | address=`expand_address "${IP}"` 63 | rev_address=`reverse_address ${address}` 64 | for char in $(echo ${rev_address} | grep -o .); do 65 | zone="${zone}${char}." 66 | done 67 | echo ${zone}ip6.arpa | cut -b 33- 68 | fi 69 | } 70 | 71 | 72 | get_ptr() { 73 | INET="${1}" 74 | IP="${2}" 75 | if [ "${INET}" = "ipv4" ]; then 76 | echo "${IP}" | /usr/bin/awk -F '.' '{print $4}' 77 | elif [ "${INET}" = "ipv6" ]; then 78 | ptr="" 79 | address=`expand_address "${IP}"` 80 | rev_address=`reverse_address ${address}` 81 | for char in $(echo ${rev_address} | grep -o .); do 82 | ptr="${ptr}${char}." 83 | done 84 | echo ${ptr} | cut -b 1-31 85 | fi 86 | } 87 | 88 | 89 | create_zone() { 90 | DOMAIN="${1}" 91 | ZONE_FILE="${ZONE_ROOT}/${DOMAIN}" 92 | if [ ! -e "${ZONE_FILE}" ]; then 93 | cat <"${ZONE_FILE}" 94 | ${DOMAIN}. SOA ${DOMAIN}. hostmaster.DOMAIN. ( 95 | 1998092901 ; Serial number 96 | 60 ; Refresh 97 | 1800 ; Retry 98 | 3600 ; Expire 99 | 1728 ) ; Minimum TTL 100 | ${DOMAIN}. NS ${DOMAIN}. 101 | 102 | \$ORIGIN ${DOMAIN}. 103 | EOF 104 | 105 | cat <>"/usr/local/etc/nsd/nsd.conf" 106 | 107 | zone: 108 | name: "${DOMAIN}" 109 | zonefile: "master/${DOMAIN}" 110 | EOF 111 | 112 | /usr/bin/mdo /usr/local/sbin/nsd-control reconfig 113 | fi 114 | } 115 | 116 | 117 | create_reverse_zone() { 118 | INET="${1}" 119 | IP="${2}" 120 | DOMAIN="${3}" 121 | REVERSE_ZONE=`get_zone ${INET} ${IP}` 122 | REVERSE_ZONE_FILE="${ZONE_ROOT}/${REVERSE_ZONE}" 123 | if [ ! -e "${REVERSE_ZONE_FILE}" ]; then 124 | cat <"${REVERSE_ZONE_FILE}" 125 | ${REVERSE_ZONE}. IN SOA ${DOMAIN}. network.${DOMAIN}. ( 126 | 46 ; serial 127 | 86400 ; refresh (1 day) 128 | 43200 ; retry (12 hours) 129 | 604800 ; expire (1 week) 130 | 10800 ; minimum (3 hours) 131 | ) 132 | IN NS network.${DOMAIN}. 133 | \$ORIGIN ${REVERSE_ZONE}. 134 | EOF 135 | 136 | cat <>"/usr/local/etc/nsd/nsd.conf" 137 | 138 | zone: 139 | name: "${REVERSE_ZONE}" 140 | zonefile: "master/${REVERSE_ZONE}" 141 | EOF 142 | 143 | /usr/bin/mdo /usr/local/sbin/nsd-control reconfig 144 | fi 145 | } 146 | 147 | 148 | cleanup() { 149 | INET="${1}" 150 | NAME="${2}" 151 | IP="${3}" 152 | DOMAIN="${4}" 153 | if [ "${INET}" = "ipv4" ]; then 154 | export RECORD="A" 155 | elif [ "${INET}" = "ipv6" ]; then 156 | export RECORD="AAAA" 157 | fi 158 | IP_REVERSE=`get_ptr ${INET} ${IP}` 159 | REVERSE_ZONE=`get_zone ${INET} ${IP}` 160 | /usr/bin/sed -i "" "/^.* *${RECORD} *${IP}$/d" "${ZONE_FILE}" 161 | /usr/bin/sed -i "" "/^${NAME} *${RECORD} /d" "${ZONE_FILE}" 162 | /usr/bin/sed -i "" "/^${IP_REVERSE} *PTR *.*/d" "${REVERSE_ZONE_FILE}" 163 | /usr/bin/sed -i "" "/^.* *PTR *${NAME}.${DOMAIN}/d" "${REVERSE_ZONE_FILE}" 164 | } 165 | 166 | 167 | alter_host() { 168 | INET="${1}" 169 | ACTION="${2}" 170 | NAME="${3}" 171 | IP="${4}" 172 | DOMAIN="${5}" 173 | IP_REVERSE=`get_ptr ${INET} ${IP}` 174 | REVERSE_ZONE=`get_zone ${INET} ${IP}` 175 | if [ "${INET}" = "ipv4" ]; then 176 | if [ "${ACTION}" = "add" ]; then 177 | if [ ! -z "${NAME}" ]; then 178 | echo "${NAME} A ${IP}" >>"${ZONE_FILE}" 179 | if [ "${NAME}" = "@" ]; then 180 | echo "${IP_REVERSE} PTR ${DOMAIN}." >>"${REVERSE_ZONE_FILE}" 181 | else 182 | echo "${IP_REVERSE} PTR ${NAME}.${DOMAIN}." >>"${REVERSE_ZONE_FILE}" 183 | fi 184 | fi 185 | echo "register ipv4 ${IP} ${NAME}.${DOMAIN}" | /usr/bin/nc -U "${SOCKET}" -w 0 186 | IP_REVERSE="${5}" 187 | elif [ "${ACTION}" = "delete" ]; then 188 | echo "unregister ipv4 ${IP} ${NAME}.${DOMAIN}" | /usr/bin/nc -U "${SOCKET}" -w 0 189 | fi 190 | elif [ "${INET}" = "ipv6" ]; then 191 | if [ "${ACTION}" = "add" ]; then 192 | if [ ! -z "${NAME}" ]; then 193 | echo "${NAME} AAAA ${IP}" >>"${ZONE_FILE}" 194 | if [ "${NAME}" = "@" ]; then 195 | echo "${IP_REVERSE} PTR ${DOMAIN}." >>"${REVERSE_ZONE_FILE}" 196 | else 197 | echo "${IP_REVERSE} PTR ${NAME}.${DOMAIN}." >>"${REVERSE_ZONE_FILE}" 198 | fi 199 | fi 200 | echo "register ipv6 ${IP} ${NAME}.${DOMAIN}" | /usr/bin/nc -U "${SOCKET}" -w 0 201 | elif [ "${ACTION}" = "delete" ]; then 202 | echo "unregister ipv6 ${IP} ${NAME}.${DOMAIN}" | /usr/bin/nc -U "${SOCKET}" -w 0 203 | fi 204 | fi 205 | /usr/bin/mdo /usr/local/sbin/nsd-control reload ${DOMAIN} 206 | /usr/bin/mdo /usr/local/sbin/nsd-control reload ${REVERSE_ZONE} 207 | } 208 | 209 | 210 | main() { 211 | INET="${1}" 212 | ACTION="${2}" 213 | IP="${3}" 214 | NAME="${4}" 215 | DOMAIN="${5}" 216 | 217 | create_zone "${DOMAIN}" 218 | create_reverse_zone "${INET}" "${IP}" "${DOMAIN}" 219 | cleanup "${INET}" "${NAME}" "${IP}" "${DOMAIN}" 220 | alter_host "${INET}" "${ACTION}" "${NAME}" "${IP}" "${DOMAIN}" 221 | } 222 | 223 | 224 | if [ "$#" = "5" ]; then 225 | INET="${1}" 226 | ACTION="${2}" 227 | IP="${3}" 228 | NAME=`echo ${4} | /usr/bin/cut -f 1 -d '.'` 229 | DOMAIN="${5}" 230 | 231 | main "${INET}" "${ACTION}" "${IP}" "${NAME}" "${DOMAIN}" 232 | elif [ "$#" != "0" ]; then 233 | echo "Usage: $0 " >&2 234 | exit 1 235 | fi 236 | -------------------------------------------------------------------------------- /man/reggae.1: -------------------------------------------------------------------------------- 1 | .Dd $Mdocdate: May 20 2018 $ 2 | .Dt REGGAE 1 3 | .Os 4 | .Sh NAME 5 | .Nm reggae 6 | .Nd \fBREG\fRister \fBG\fRlobaly \fBA\fRccess \fBEv\fRerywhere is a package 7 | which helps in common DevOps tasks 8 | .Sh SYNOPSIS 9 | .Nm reggae 10 | .Sh DESCRIPTION 11 | .Pp 12 | \fBReggae\fR is an open source package which relays on base \fBFreeBSD\fR 13 | and/or \fBCBSD\fR to provide lower level management for jails and virtual 14 | machines. 15 | .Pp 16 | If you have ever used Vagrant or Docker Compose, Reggae is best described as an 17 | alternative to those. It enables you easy development inside jail while code 18 | editing is done on the host. It makes transition from development to production 19 | easier by using provisioners. It makes host clean of all requirements of 20 | development and puts them inside jail which is easily stopped, started, 21 | provisioned, and destroyed. 22 | .Pp 23 | To initialize Reggae, first edit /usr/local/etc/reggae.conf and add: 24 | .Pp 25 | .Dl PROJECTS_DIR=/home/me/repos 26 | .Pp 27 | It will set directory to be shared with virtual machines, like directory 28 | containing your projects. If you don't need such a directory, you can set it to 29 | /var/empty. 30 | .Pp 31 | .Dl PROJECTS_DIR=/var/empty 32 | .Pp 33 | If you want to run Reggae with base jails, no need to do any other edits, but 34 | if you'd like to use \fBCBSD\fR as the backend, you need to add 35 | .Pp 36 | .Dl BACKEND=cbsd 37 | .Pp 38 | run the following as root: 39 | .Pp 40 | .Dl reggae host-init 41 | .Dl # service pflog restart 42 | .Dl # service pf restart 43 | .Dl reggae backend-init 44 | .Dl reggae network-init 45 | .Pp 46 | PF is initialized only if /etc/pf.conf doesn't exist already. In those cases PF 47 | services should be restarted. 48 | .Pp 49 | Through config file in /usr/local/etc/reggae.conf you can change values for 50 | anything Reggae is using. Ater \fBreggae network-init\fR, you'll get jail 51 | containing DHCP and DNS. They are used to lease IPs to jails and virtual 52 | machines and to register all resources in DNS so that you can use FQDN instead 53 | of IP addresses. This jail IP is used in /etc/resolvconf.conf if host has 54 | dynamic IP on egress, so that changes of network parameters are passed to the 55 | appropriate jail. Also, host will use DNS jail IP in /etc/resolv.conf. In 56 | short, it enables you to not remember jail IPs when you have to use them, 57 | but use . to reference them. 58 | .Sh PROJECT 59 | .Pp 60 | A project consists of: 61 | .Bl -bullet 62 | .It 63 | \fBMakefile\fR - configured for use with project 64 | .El 65 | .Pp 66 | One project can contain many services, and that's going to be shown in the 67 | generated Makefile. The SERVICES variable in it will be commented but populated 68 | with example services. All services when downloaded will be in 69 | services/ directory. You can use preexisting services if you define 70 | \fBUSE = \fR. For example, you can write the following: 71 | .Pp 72 | .Dl REGGAE_PATH = /usr/local/share/reggae 73 | .Dl USE = letsencrypt mysql wordpress nginx 74 | .Dl .include <${REGGAE_PATH}/mk/project.mk> 75 | .Pp 76 | This project will set Wordpress in a jail. 77 | .Pp 78 | You can run \fBmake \fR on the project: 79 | .Bl -bullet -offset indent -compact 80 | .It 81 | destroy 82 | .It 83 | devel 84 | .It 85 | fetch 86 | .It 87 | init 88 | .It 89 | login service= 90 | .It 91 | provision 92 | .It 93 | setup 94 | .It 95 | up 96 | .El 97 | .Pp 98 | Special note for the devel target: your repo must have bin/devel.sh which will 99 | be run on the host. All project targets can be suffixed with service= 100 | but in the above list only those which require a service are explicitely 101 | mentioned. If the service is passed as an argument, the target will be 102 | executed only on that service/jail. 103 | .Sh ANSIBLE 104 | .Pp 105 | A service with ansible provisioner consists of: 106 | .Bl -bullet 107 | .It 108 | \fBMakefile\fR - configured for use with Ansible 109 | .It 110 | \fBplaybook\fR - containing group_vars, inventory and roles directories as placeholders for files generated on the fly, but can be used to configure your playbook 111 | .It 112 | \fBrequirements.yml\fR - list of requirements, with only one initially. All requirements from this file are downloaded from Ansible Galaxy 113 | templates/site.yml.tpl - this file should be edited to add/remove roles, playbooks, etc. 114 | .El 115 | .Pp 116 | When ran with this configuration, reggae will first check if ansible executable 117 | is available on the host, and if it isn't, it will run \fBpkg install ansible\fR. 118 | If you use Python's virtual environments, for example, you can avoid having 119 | ansible available to everyone on the system. 120 | .Sh CHEF 121 | .Pp 122 | A service with chef provisioner consists of: 123 | .Bl -bullet 124 | .It 125 | \fBMakefile\fR - configured for use with chef 126 | .It 127 | \fBplaybook\fR - containing cookbooks/core/recipes/default.rb dummy script 128 | .El 129 | .Pp 130 | When ran with this configuration, reggae will first check if chef executable 131 | is available, and if it isn't, it will run \fBpkg install -y chef\fR inside 132 | jail. Then it will mount playbook directory on /root/chef inside jail. To do 133 | actual provisioning, Reggae uses \fBchef-client --local-mode\fR. 134 | .Sh PUPPET 135 | .Pp 136 | A service with puppet provisioner consists of: 137 | .Bl -bullet 138 | .It 139 | \fBMakefile\fR - configured for use with puppet 140 | .It 141 | \fBplaybook\fR - containing cookbooks/core/recipes/default.rb dummy script 142 | .El 143 | .Pp 144 | When ran with this configuration, reggae will first check if puppet executable 145 | is available inside jail, and if it isn't, it will install it from packages. 146 | Then it will mount playbook directory on /usr/local/etc/puppet/manifests inside 147 | jail. To do actual provisioning, Reggae uses \fBpuppet apply\fR. 148 | .Sh SALT STACK 149 | .Pp 150 | A service with salt provisioner consists of: 151 | .Bl -bullet 152 | .It 153 | \fBMakefile\fR - configured for use with salt 154 | .It 155 | \fBplaybook\fR - containing top.sls and core.sls playbooks 156 | .El 157 | .Pp 158 | When ran with this configuration, reggae will first check if salt executable is 159 | available, and if it isn't, it will run \fBpkg install -y py36-salt\fR inside 160 | jail. Then it will mount playbook directory on /usr/local/etc/salt/states inside 161 | jail. To do actual provisioning, Reggae uses \fBsalt-call --local state.apply\fR. 162 | .Sh SHELL 163 | .Pp 164 | A service with shell provisioner consists of: 165 | .Bl -bullet 166 | .It 167 | \fBMakefile\fR - configured for use with shell 168 | .It 169 | \fBplaybook\fR - containing dummy provision.sh to start with 170 | .El 171 | .Pp 172 | When ran with this configuration, reggae will first mount playbook directory on 173 | /root/shell inside jail. To do actual provisioning, Reggae will run 174 | \fB/root/shell/provision.sh\fR. 175 | .Sh EXAMPLES 176 | .Pp 177 | Quickest way to get basic project is: 178 | .Pp 179 | .Dl mkdir myproject 180 | .Dl cd myproject 181 | .Dl reggae init-project 182 | .Pp 183 | Quickest way to get basic service provisioned with Ansible is: 184 | .Pp 185 | .Dl mkdir myservice 186 | .Dl cd myservice 187 | .Dl reggae init shell 188 | .Dl make 189 | .Pp 190 | You can have multiple provisioners, and the order they are declared on the 191 | command line is the order they will be executed in. 192 | .Pp 193 | .Dl mkdir myservice 194 | .Dl cd myservice 195 | .Dl reggae init shell ansible 196 | .Dl make 197 | .Sh SEE ALSO 198 | .Xr jail 8 199 | .Xr bhyve 8 200 | .Sh BUGS 201 | Report bugs to https://github.com/cbsd/reggae/issues. 202 | .Sh AUTHORS 203 | Goran Mekić 204 | -------------------------------------------------------------------------------- /scripts/mkjail.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ -f "/usr/local/etc/reggae.conf" ]; then 6 | . "/usr/local/etc/reggae.conf" 7 | fi 8 | 9 | SCRIPT_DIR=$(dirname $0) 10 | . "${SCRIPT_DIR}/default.conf" 11 | . "${SCRIPT_DIR}/utils.sh" 12 | 13 | if [ "${USE_IPV4}" != "yes" -a "${USE_IPV6}" != "yes" ]; then 14 | echo "IPv4 and/or IPv6 has to be enable, check USE_IPV{4,6} in config!" >&2 15 | exit 1 16 | fi 17 | 18 | help() { 19 | echo "Usage: ${0} [options] " 20 | echo "" 21 | echo "options:" 22 | echo " -d " 23 | echo " Lilt of jails this jail depends on." 24 | echo " -f " 25 | echo " Aditional mount points defined in ." 26 | } 27 | 28 | UPDATE=${UPDATE:=yes} 29 | DEPS="" 30 | FSTAB="" 31 | optstring="d:f:" 32 | args=$(getopt "${optstring}" ${*}) 33 | if [ $? -ne 0 ]; then 34 | help >&2 35 | exit 1 36 | fi 37 | set -- ${args} 38 | while :; do 39 | case "${1}" in 40 | -d) 41 | DEPS="${2}" 42 | shift; shift 43 | ;; 44 | -f) 45 | FSTAB="${2}" 46 | shift; shift 47 | ;; 48 | --) 49 | shift 50 | break 51 | ;; 52 | esac 53 | done 54 | 55 | 56 | NAME="${1}" 57 | if [ -z "${NAME}" ]; then 58 | help >&2 59 | exit 1 60 | fi 61 | 62 | 63 | POOL="${POOL:=zroot}" 64 | export BSDINSTALL_CHROOT="${BASE_WORKDIR}/${NAME}" 65 | if [ "${PKG_PROXY}" != "no" ]; then 66 | export HTTP_PROXY="${PKG_PROXY}" 67 | fi 68 | 69 | 70 | get_mounts() { 71 | if [ -z "${FSTAB}" ]; then 72 | return 73 | fi 74 | if [ -f "${FSTAB}" ]; then 75 | cat "${FSTAB}" | while read mountpoint; do 76 | mount_dest=$(eval echo ${mountpoint} | awk '{print $2}') 77 | mkdir -p "${BSDINSTALL_CHROOT}${mount_dest}" 78 | echo -n "\n mount += \"${mountpoint}\";" 79 | done 80 | fi 81 | } 82 | 83 | 84 | get_dependencies() { 85 | if [ -z "${DEPS}" ]; then 86 | return 87 | fi 88 | echo -n " depend = ${DEPS};" 89 | } 90 | 91 | 92 | generate_mac() { 93 | echo -n "58:9c:fc:" 94 | hexdump -n 3 -ve '1/1 "%.2x "' /dev/random |\ 95 | awk -v a="2,3,a,e" -v r="$RANDOM" ' 96 | BEGIN { 97 | srand(r); 98 | } 99 | NR==1 { 100 | split(a, b, ","); 101 | r=int(rand() * 4 + 1); 102 | printf("%s%s:%s:%s", substr($1, 0, 1), b[r], $2, $3); 103 | } 104 | ' 105 | } 106 | 107 | check "${NAME}" "${BSDINSTALL_CHROOT}" 108 | 109 | if [ "${USE_ZFS}" = "yes" ]; then 110 | zfs create -p "${POOL}${BSDINSTALL_CHROOT}" 111 | else 112 | mkdir -p "${BSDINSTALL_CHROOT}" 113 | fi 114 | 115 | mkdir -p "${BSDINSTALL_CHROOT}/usr/local/etc/pkg/repos" 116 | cat <"${BSDINSTALL_CHROOT}/usr/local/etc/pkg/repos/FreeBSD.conf" 117 | FreeBSD-ports: { url: "pkg+https://pkg.FreeBSD.org/\${ABI}/latest" } 118 | FreeBSD-base: { 119 | url: "pkg+https://pkg.FreeBSD.org/\${ABI}/base_release_\${VERSION_MINOR}", 120 | enabled: yes 121 | } 122 | EOF 123 | 124 | mkdir -p "${BSDINSTALL_CHROOT}/usr/share/keys" 125 | cp -r /usr/share/keys/* "${BSDINSTALL_CHROOT}/usr/share/keys" 126 | 127 | mkdir "${BSDINSTALL_CHROOT}/dev" 128 | mount -t devfs devfs "${BSDINSTALL_CHROOT}/dev" 129 | 130 | pkg -r "${BSDINSTALL_CHROOT}" install -y FreeBSD-set-minimal-jail 131 | cp /etc/resolv.conf "${BSDINSTALL_CHROOT}/etc" 132 | env ASSUME_ALWAYS_YES=YES pkg -c "${BSDINSTALL_CHROOT}" bootstrap -f 133 | if [ "${PKG_PROXY}" != "no" ]; then 134 | echo "pkg_env : { http_proxy: \"http://${PKG_PROXY}/\" }" >>"${BSDINSTALL_CHROOT}/usr/local/etc/pkg.conf" 135 | fi 136 | pkg -r "${BSDINSTALL_CHROOT}" install -y FreeBSD-ssh 137 | 138 | sysrc -R "${BSDINSTALL_CHROOT}" hostname="${NAME}.${DOMAIN}" 139 | sysrc -R "${BSDINSTALL_CHROOT}" sshd_enable="YES" 140 | sysrc -R "${BSDINSTALL_CHROOT}" ifconfig_eth0="SYNCDHCP" 141 | echo "security.mac.do.rules=gid=0:any" >>"${BSDINSTALL_CHROOT}/etc/sysctl.conf" 142 | 143 | umount "${BSDINSTALL_CHROOT}/dev" 144 | 145 | echo "domain ${DOMAIN}" >"${BSDINSTALL_CHROOT}/etc/resolv.conf" 146 | if [ -n "${DNS_OVERRIDE}" ]; then 147 | for nameserver in ${DNS_OVERRIDE}; do 148 | echo "nameserver ${nameserver}" >>"${BSDINSTALL_CHROOT}/etc/resolv.conf" 149 | done 150 | else 151 | if [ "${USE_IPV4}" = "yes" ]; then 152 | echo "nameserver ${INTERFACE_IP}" >>"${BSDINSTALL_CHROOT}/etc/resolv.conf" 153 | fi 154 | if [ "${USE_IPV6}" = "yes" ]; then 155 | echo "nameserver ${IPV6_PREFIX}${INTERFACE_IP6}" >>"${BSDINSTALL_CHROOT}/etc/resolv.conf" 156 | fi 157 | fi 158 | chroot "${BSDINSTALL_CHROOT}" pw group add provision -g 666 159 | chroot "${BSDINSTALL_CHROOT}" pw user add provision -u 666 -g provision -s /bin/sh -G wheel -m 160 | chroot "${BSDINSTALL_CHROOT}" chpass -p '$6$61V0w0dRFFiEcnm2$o8CLPIdRBVHP13LQizdp12NEGD91RfHSB.c6uKnr9m2m3ZCg7ASeGENMaDt0tffmo5RalKGjWiHCtScCtjYfs/' provision 161 | chroot "${BSDINSTALL_CHROOT}" service sshd enable 162 | mkdir -p "${BSDINSTALL_CHROOT}/home/provision/.ssh" 163 | chmod 700 "${BSDINSTALL_CHROOT}/home/provision/.ssh" 164 | # TODO: specify key 165 | cp ~/.ssh/id_rsa.pub "${BSDINSTALL_CHROOT}/home/provision/.ssh/authorized_keys" 166 | chmod 600 "${BSDINSTALL_CHROOT}/home/provision/.ssh/authorized_keys" 167 | chown -R 666:666 "${BSDINSTALL_CHROOT}/home/provision/.ssh" 168 | if [ "${NAME}" != "network" ]; then 169 | if [ "${DHCP}" = "dhcpcd" ]; then 170 | pkg -c "${BSDINSTALL_CHROOT}" install -y dhcpcd 171 | echo dhclient_program=\"/usr/local/sbin/dhcpcd\" >>${BSDINSTALL_CHROOT}/etc/rc.conf 172 | sed -i "" -e \ 173 | "s/^#hostname/hostname/" \ 174 | "${BSDINSTALL_CHROOT}/usr/local/etc/dhcpcd.conf" 175 | echo ipv6ra_noautoconf >>"${BSDINSTALL_CHROOT}/usr/local/etc/dhcpcd.conf" 176 | sysrc -R "${BSDINSTALL_CHROOT}" ifconfig_eth0="SYNCDHCP" 177 | else 178 | if [ "${USE_IPV4}" = "yes" ]; then 179 | sysrc -R "${BSDINSTALL_CHROOT}" ifconfig_eth0="SYNCDHCP" 180 | fi 181 | if [ "${USE_IPV6}" = "yes" ]; then 182 | sysrc -R "${BSDINSTALL_CHROOT}" ifconfig_eth0_ipv6="inet6 -ifdisabled accept_rtadv auto_linklocal" 183 | fi 184 | fi 185 | fi 186 | echo pf_enable=\"YES\" >>${BSDINSTALL_CHROOT}/etc/rc.conf 187 | echo pflog_enable=\"YES\" >>${BSDINSTALL_CHROOT}/etc/rc.conf 188 | cp "${SCRIPT_DIR}/../templates/pf-jail.conf" "${BSDINSTALL_CHROOT}/etc/pf.conf" 189 | touch "${BSDINSTALL_CHROOT}/etc/pf.services" 190 | if [ -n "${PORTS}" ]; then 191 | ports="" 192 | for port in ${PORTS}; do 193 | if [ -z "${ports}" ]; then 194 | ports="${port}" 195 | else 196 | ports="${ports}, ${port}" 197 | fi 198 | done 199 | echo "pass in proto { tcp, udp } to (self) port { $ports }" >"${BSDINSTALL_CHROOT}/etc/pf.services" 200 | fi 201 | 202 | ID=$(next_id) 203 | HOST=$(hostname) 204 | 205 | if [ ! -e "/etc/jail.conf.d/reggae.inc" ]; then 206 | sed \ 207 | -e "s;HOST;${HOST};g" \ 208 | -e "s;BASE_WORKDIR;${BASE_WORKDIR};g" \ 209 | -e "s;INTERFACE;${INTERFACE};g" \ 210 | "${SCRIPT_DIR}/../templates/base-jail.conf" >>"/etc/jail.conf.d/reggae.inc" 211 | fi 212 | cat << EOF >"/etc/jail.conf.d/${NAME}.conf" 213 | ${NAME} { 214 | \$id = ${ID}; 215 | .include "/etc/jail.conf.d/reggae.inc"; 216 | EOF 217 | if [ "${NAME}" = "network" ]; then 218 | sysrc -R "${BSDINSTALL_CHROOT}" ifconfig_eth0_alias0="ether 58:9c:fc:00:00:00" 219 | echo -e "}" >>"/etc/jail.conf.d/${NAME}.conf" 220 | else 221 | MAC=$(generate_mac) 222 | MOUNTS=$(get_mounts) 223 | DEPENDS=$(get_dependencies) 224 | pkg -r "${BSDINSTALL_CHROOT}" install -y dhcpcd 225 | sysrc -R "${BSDINSTALL_CHROOT}" ifconfig_eth0_alias0="ether ${MAC}" 226 | sysrc -R "${BSDINSTALL_CHROOT}" dhclient_program="/usr/local/sbin/dhcpcd" 227 | if [ ! -z "${PRESTART}" ]; then 228 | PRESTART="\n exec.prestart += \"${PRESTART}\";" 229 | fi 230 | if [ ! -z "${POSTSTART}" ]; then 231 | POSTSTART="\n exec.poststart += \"${POSTSTART}\";" 232 | fi 233 | if [ ! -z "${PRESTOP}" ]; then 234 | PRESTOP="\n exec.prestop += \"${PRESTOP}\";" 235 | fi 236 | if [ ! -z "${POSTSTOP}" ]; then 237 | POSTSTOP="\n exec.poststop += \"${POSTSTOP}\";" 238 | fi 239 | for option in ${ALLOW}; do 240 | JAIL_ALLOW="\n allow.${option};${JAIL_ALLOW}" 241 | done 242 | OPTIONS="${JAIL_ALLOW}${MOUNTS}${DEPENDS}${PRESTART}${POSTSTART}${PRESTOP}${POSTSTOP}" 243 | echo -e "${OPTIONS}\n}" >>"/etc/jail.conf.d/${NAME}.conf" 244 | fi 245 | -------------------------------------------------------------------------------- /mk/cbsd-jail.mk: -------------------------------------------------------------------------------- 1 | SUBTYPE ?= vnet 2 | DHCP ?= dhcpcd 3 | CBSD_WORKDIR != sysrc -s cbsdd -n cbsd_workdir 4 | INTERFACE != reggae get-config INTERFACE 5 | PKG_MIRROR_CONFIG != reggae get-config PKG_MIRROR 6 | PKG_REPO_CONFIG != reggae get-config PKG_REPO 7 | PKG_PROXY_CONFIG != reggae get-config PKG_PROXY 8 | PKG_MIRROR ?= ${PKG_MIRROR_CONFIG} 9 | PKG_REPO ?= ${PKG_REPO_CONFIG} 10 | PKG_PROXY ?= ${PKG_PROXY_CONFIG} 11 | DEVFS_RULESET ?= 8 12 | 13 | 14 | .if target(pre_up) 15 | up: setup pre_up 16 | .else 17 | up: setup 18 | .endif 19 | @mdo cbsd jstart ${SERVICE} || true 20 | .if exists(cbsd.conf) 21 | @mdo chown ${UID}:${GID} cbsd.conf 22 | .endif 23 | .if !exists(${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/sbin/pkg) 24 | @mdo cbsd jexec jname=${SERVICE} cmd="env ASSUME_ALWAYS_YES=yes pkg bootstrap -f" 25 | @mdo cbsd jexec jname=${SERVICE} cmd="pkg install -y mdo ${EXTRA_PACKAGES}" 26 | .endif 27 | .if ${SUBTYPE} != "linux" 28 | .if !exists(${CBSD_WORKDIR}/jails-data/${SERVICE}-data/etc/rc.conf.d/network) 29 | @mdo cp ${REGGAE_PATH}/templates/network ${CBSD_WORKDIR}/jails-data/${SERVICE}-data/etc/rc.conf.d/network 30 | .if ${DHCP} == "dhcpcd" 31 | @mdo cbsd jexec jname=${SERVICE} cmd="pkg install -y dhcpcd" 32 | @mdo sed -i "" -e \ 33 | "s/^#hostname/hostname/" \ 34 | ${BASE_WORKDIR}/${SERVICE}/usr/local/etc/dhcpcd.conf 35 | @mdo sed -i "" \ 36 | -e "s:DHCP:/usr/local/sbin/dhcpcd:g" \ 37 | ${CBSD_WORKDIR}/jails-data/${SERVICE}-data/etc/rc.conf.d/network 38 | @mdo cbsd jexec jname=${SERVICE} cmd="/bin/pkill -9 dhclient" 39 | @mdo cbsd jexec jname=${SERVICE} cmd="/sbin/ifconfig eth0 delete" 40 | @mdo cbsd jexec jname=${SERVICE} cmd="dhcpcd eth0" 41 | @mdo env jname=${SERVICE} ${CBSD_WORKDIR}/jails-system/${SERVICE}/master_poststart.d/export-ports.sh 42 | .else 43 | @mdo sed -i "" \ 44 | -e "s:DHCP:/sbin/dhclient:g" \ 45 | ${CBSD_WORKDIR}/jails-data/${SERVICE}-data/etc/rc.conf.d/network 46 | .endif 47 | .endif 48 | .endif 49 | .if ${DEVEL_MODE} == "YES" 50 | .if !exists(${CBSD_WORKDIR}/jails-data/${SERVICE}-data/home/devel) 51 | @mdo cbsd jexec jname=${SERVICE} cmd="pw groupadd devel -g ${GID}" 52 | @mdo cbsd jexec jname=${SERVICE} cmd="pw useradd devel -u ${UID} -g devel -s /bin/tcsh -G wheel,operator -m" 53 | @mdo cbsd jexec jname=${SERVICE} cmd="chpass -p '$6$MIv4IXAika7jqFH2$GkYSBax0G9CIBG0DcgQMP5gG7Qt.CojExDcU7YOQy0K.pouAd.edvo/MaQPhVO0fISxjOD4J1nzRsGVXUAxGp1' devel" 54 | .endif 55 | .else 56 | @echo 'Deleting user "devel"' 57 | -@mdo cbsd jexec jname=${SERVICE} cmd="pw user del devel -r >/dev/null 2>&1" 58 | @echo 'User "devel" deleted' 59 | .endif 60 | @mdo cbsd jexec jname=${SERVICE} cmd="pwd_mkdb /etc/master.passwd" 61 | .if target(post_up) 62 | @${MAKE} ${MAKEFLAGS} post_up 63 | .endif 64 | .if !exists(${CBSD_WORKDIR}/jails-system/${SERVICE}/.provisioned) 65 | @${MAKE} ${MAKEFLAGS} provision 66 | .endif 67 | 68 | provision: setup 69 | -@mdo touch ${CBSD_WORKDIR}/jails-system/${SERVICE}/.provisioned 70 | .for provisioner in ${PROVISIONERS} 71 | @${MAKE} ${MAKEFLAGS} provision-${provisioner} 72 | .endfor 73 | 74 | .if target(pre_down) 75 | down: setup pre_down 76 | .else 77 | down: setup 78 | .endif 79 | @mdo cbsd jstop ${SERVICE} || true 80 | .if target(post_down) 81 | @${MAKE} ${MAKEFLAGS} post_down 82 | .endif 83 | 84 | .if target(pre_destroy) 85 | destroy: pre_destroy 86 | .else 87 | destroy: 88 | .endif 89 | @rm -f cbsd.conf .provisioned 90 | @mdo cbsd jremove ${SERVICE} 91 | .for provisioner in ${PROVISIONERS} 92 | @${MAKE} ${MAKEFLAGS} clean-${provisioner} 93 | .endfor 94 | .if target(post_destroy) 95 | @${MAKE} ${MAKEFLAGS} post_destroy 96 | .endif 97 | 98 | .if target(pre_setup) 99 | setup: pre_setup 100 | .else 101 | setup: 102 | .endif 103 | .if $(SUBTYPE) == "vnet" 104 | @sed \ 105 | -e "s:SERVICE:${SERVICE}:g" \ 106 | -e "s:DOMAIN:${DOMAIN}:g" \ 107 | -e "s:CBSD_WORKDIR:${CBSD_WORKDIR}:g" \ 108 | -e "s:EXTRA_PACKAGES:${EXTRA_PACKAGES}:g" \ 109 | -e "s:INTERFACE:${INTERFACE}:g" \ 110 | -e "s:VERSION:${VERSION}:g" \ 111 | -e "s:DEVFS_RULESET:${DEVFS_RULESET}:g" \ 112 | ${REGGAE_PATH}/templates/cbsd-vnet.conf.tpl >cbsd.conf 113 | .elif $(SUBTYPE) == "linux" 114 | @sed \ 115 | -e "s:SERVICE:${SERVICE}:g" \ 116 | -e "s:DOMAIN:${DOMAIN}:g" \ 117 | -e "s:CBSD_WORKDIR:${CBSD_WORKDIR}:g" \ 118 | -e "s:INTERFACE:${INTERFACE}:g" \ 119 | ${REGGAE_PATH}/templates/linux.conf.tpl >cbsd.conf 120 | .else 121 | @sed \ 122 | -e "s:SERVICE:${SERVICE}:g" \ 123 | -e "s:DOMAIN:${DOMAIN}:g" \ 124 | -e "s:CBSD_WORKDIR:${CBSD_WORKDIR}:g" \ 125 | -e "s:EXTRA_PACKAGES:${EXTRA_PACKAGES}:g" \ 126 | -e "s:INTERFACE:${INTERFACE}:g" \ 127 | -e "s:DEVFS_RULESET:${DEVFS_RULESET}:g" \ 128 | -e "s:VERSION:${VERSION}:g" \ 129 | ${REGGAE_PATH}/templates/cbsd.conf.tpl >cbsd.conf 130 | .endif 131 | .for provisioner in ${PROVISIONERS} 132 | @${MAKE} ${MAKEFLAGS} setup-${provisioner} 133 | .endfor 134 | .if target(post_setup) 135 | @${MAKE} ${MAKEFLAGS} post_setup 136 | .endif 137 | @mdo cbsd jcreate jconf=${PWD}/cbsd.conf || true 138 | .if exists(${EXTRA_FSTAB}) 139 | @mdo cp ${EXTRA_FSTAB} ${CBSD_WORKDIR}/jails-fstab/fstab.${SERVICE}.local 140 | .else 141 | @mdo rm -rf ${CBSD_WORKDIR}/jails-fstab/fstab.${SERVICE}.local 142 | .endif 143 | .if ${DEVEL_MODE} == "YES" 144 | @mdo sh -c "echo ${PWD} /usr/src nullfs rw 0 0 >>${CBSD_WORKDIR}/jails-fstab/fstab.${SERVICE}.local" 145 | @mdo cbsd jset jname=${SERVICE} astart=0 146 | .else 147 | @mdo cbsd jset jname=${SERVICE} astart=1 148 | .endif 149 | .if ${SUBTYPE} != "linux" 150 | .if !exists(${CBSD_WORKDIR}/jails-data/${SERVICE}-data/home/provision/.ssh/authorized_keys) 151 | .if !exists(${CBSD_WORKDIR}/jails-data/${SERVICE}-data/home/provision/.ssh) 152 | -@mdo mkdir ${CBSD_WORKDIR}/jails-data/${SERVICE}-data/home/provision/.ssh 153 | .endif 154 | @mdo chmod 700 ${CBSD_WORKDIR}/jails-data/${SERVICE}-data/home/provision/.ssh 155 | @mdo cp ~/.ssh/id_rsa.pub ${CBSD_WORKDIR}/jails-data/${SERVICE}-data/home/provision/.ssh/authorized_keys 156 | @mdo chmod 600 ${CBSD_WORKDIR}/jails-data/${SERVICE}-data/home/provision/.ssh/authorized_keys 157 | @mdo chown -R 666:666 ${CBSD_WORKDIR}/jails-data/${SERVICE}-data/home/provision/.ssh 158 | .endif 159 | .endif 160 | @mdo cp ${REGGAE_PATH}/templates/export-ports.sh ${CBSD_WORKDIR}/jails-system/${SERVICE}/master_poststart.d 161 | @mdo sed -i "" \ 162 | -e "s;PRTS;${PORTS};g" \ 163 | ${CBSD_WORKDIR}/jails-system/${SERVICE}/master_poststart.d/export-ports.sh 164 | @mdo chmod 700 ${CBSD_WORKDIR}/jails-system/${SERVICE}/master_poststart.d/export-ports.sh 165 | @mdo cp ${REGGAE_PATH}/templates/xorg.sh ${CBSD_WORKDIR}/jails-system/${SERVICE}/master_poststart.d 166 | @mdo sed -i "" \ 167 | -e "s:XORG:${XORG}:g" \ 168 | ${CBSD_WORKDIR}/jails-system/${SERVICE}/master_poststart.d/xorg.sh 169 | @mdo chmod 700 ${CBSD_WORKDIR}/jails-system/${SERVICE}/master_poststart.d/xorg.sh 170 | .if !exists(${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/etc/pkg/repos) 171 | @mdo mkdir -p ${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/etc/pkg/repos 172 | @mdo sh -c 'echo -e FreeBSD: { url: \"pkg+http://${PKG_MIRROR}/\$${ABI}/${PKG_REPO}\"\; } >${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/etc/pkg/repos/FreeBSD.conf' 173 | .endif 174 | .if !exists(${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/etc/pkg.conf) 175 | .if ${PKG_PROXY} != no 176 | @mdo cp ${REGGAE_PATH}/templates/pkg.conf ${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/etc/ 177 | @mdo sed -i "" \ 178 | -e 's;PKG_PROXY;pkg_env : { http_proxy: "http://${PKG_PROXY}" };g' \ 179 | ${CBSD_WORKDIR}/jails-data/${SERVICE}-data/usr/local/etc/pkg.conf 180 | .endif 181 | .endif 182 | .if ${SUBTYPE} != "linux" 183 | @mdo cp ${REGGAE_PATH}/templates/netif ${CBSD_WORKDIR}/jails-data/${SERVICE}-data/etc/rc.conf.d/ 184 | .if ${DHCP} != "dhcpcd" 185 | @mdo cp ${REGGAE_PATH}/templates/rtsold ${CBSD_WORKDIR}/jails-data/${SERVICE}-data/etc/rc.conf.d/ 186 | .endif 187 | .endif 188 | .if target(post_create) 189 | @${MAKE} ${MAKEFLAGS} post_create 190 | .endif 191 | 192 | login: 193 | .if defined(user) 194 | @mdo cbsd jlogin user=${user} ${SERVICE} 195 | .else 196 | @mdo cbsd jlogin ${SERVICE} 197 | .endif 198 | 199 | exec: 200 | @mdo cbsd jexec jname=${SERVICE} cmd="${command}" 201 | 202 | .if target(pre_export) 203 | export: down pre_export 204 | .else 205 | export: down 206 | .if !exists(build) 207 | @mkdir build 208 | .endif 209 | @mdo cbsd jexport jname=${SERVICE} 210 | @echo "Moving ${SERVICE}.img to build dir ..." 211 | @mdo mv ${CBSD_WORKDIR}/export/${SERVICE}.img build/ 212 | @echo "Chowning ${SERVICE}.img to ${UID}:${GID} ..." 213 | @mdo chown ${UID}:${GID} build/${SERVICE}.img 214 | .if target(post_export) 215 | @${MAKE} ${MAKEFLAGS} post_export 216 | .endif 217 | .endif 218 | 219 | devel_check: 220 | .if ${DEVEL_MODE} != "YES" 221 | @echo "DEVEL_MODE must be set to YES" 222 | @exit 1 223 | .endif 224 | 225 | .if target(do_devel) 226 | devel: devel_check up do_devel 227 | .else 228 | devel: devel_check up 229 | @mdo cbsd jexec jname=${SERVICE} user=devel cmd="env OFFLINE=${offline} SYSPKG=${SYSPKG} /usr/src/bin/devel.sh" 230 | .if target(post_devel) 231 | @${MAKE} ${MAKEFLAGS} post_devel 232 | .endif 233 | .endif 234 | 235 | .if target(do_test) 236 | test: up do_test 237 | .else 238 | test: up 239 | @mdo cbsd jexec jname=${SERVICE} user=devel cmd="env OFFLINE=${offline} SYSPKG=${SYSPKG} /usr/src/bin/test.sh" 240 | .endif 241 | 242 | upgrade: up 243 | @mdo cbsd jexec jname=${SERVICE} cmd="pkg upgrade -y" 244 | --------------------------------------------------------------------------------