diff --git a/TODO.md b/TODO.md index b05a864..ef74991 100644 --- a/TODO.md +++ b/TODO.md @@ -27,20 +27,8 @@ or using e3 using wrapper script around `jaildk exec dns knotc ...` - remove pkg function from root .bashrc -## Add users with authorized_keys files - -Users script ready, add ssh keys support - ## Add quota config and enable/configure rctl -## DNS +## SSH Keys -- kresd.conf => listen on :: -- add ::1 to host resolv.conf -- add default gw to jail resolv.conf - -## Network - -- {{ ansible_default_ipv6.interface }} sometimes resolves to the link local ip, not the inet6 one, which results in a wrong (or none) default route and resolve.conf inside the jail. - -- Use https://danwin1210.de/github-ipv6-proxy.php +Use ansible-vault to encrypt them diff --git a/debug.yaml b/debug.yaml index 7e220e9..2720627 100644 --- a/debug.yaml +++ b/debug.yaml @@ -6,3 +6,4 @@ user: root roles: - role: network + - role: user diff --git a/roles/pubnix/bin/user.sh b/roles/pubnix/bin/user.sh index 9c53d74..d51f4ad 100755 --- a/roles/pubnix/bin/user.sh +++ b/roles/pubnix/bin/user.sh @@ -1,5 +1,8 @@ #!/bin/sh +# manage FreeBSD jail users + +# vars defaults rootdir="" user="" groups="" @@ -14,11 +17,22 @@ usage() { exit 1 } -run() { - echo $* - $* +getuid() { + # resolve jail uid + + root="$1" + user="$2" + pw $root show user "$user" -7 | cut -d: -f 3 } +run() { + # verbose exec + + echo "$@" + "$@" +} + +# parse commandline flags OPTIND=1 while getopts d:u:h:g:s:c:a: opt ; do case $opt in @@ -55,6 +69,7 @@ if test -z "$user" -o -z "$action"; then usage fi +# setup pw flags args="" root="" @@ -82,20 +97,31 @@ if test -n "$comment"; then args="$args -c $comment" fi +# the horse shall work case "$action" in present) if pw $root user show "$user" > /dev/null 2>&1; then if pw $root user show "$user" | grep -q LOCKED; then + # user is present but locked run pw unlock "$user" else echo "$user exists." fi else + # create user run pw $root user add "$user" $args fi + + if test -e "/usr/local/bastille/keys/$user" -a ! -e "/home/$user/.ssh/authorized_keys"; then + # install ssh key + uid=$(getuid "$root" "$user") + install -m 700 -o "$uid" -g "$uid" -d "/home/$user/.ssh" + install -m 600 -o "$uid" -g "$uid" "/usr/local/bastille/keys/$user" "/home/$user/.ssh/authorized_keys" + fi ;; absent) if pw $root user show "$user" > /dev/null 2>&1; then + # get rid run pw $root user del "$user" fi ;; @@ -104,6 +130,7 @@ case "$action" in if pw $root user show "$user" | grep -q LOCKED; then echo "$user is already locked." else + # lock'em out run pw lock "$user" fi fi diff --git a/roles/pubnix/files/skel/dot.bashrc b/roles/pubnix/files/skel/dot.bash_profile similarity index 80% rename from roles/pubnix/files/skel/dot.bashrc rename to roles/pubnix/files/skel/dot.bash_profile index 7d4676d..a0b4bc6 100755 --- a/roles/pubnix/files/skel/dot.bashrc +++ b/roles/pubnix/files/skel/dot.bash_profile @@ -102,22 +102,24 @@ alias uc="tr '[a-z]' '[A-Z]'" alias table="column -t" alias gethttp="fetch -n --no-verify-peer --no-verify-hostname" +# use vim +alias vi=vim +EDITOR=vim -PROMPT_COMMAND="PS1='\[\033]0;\u@$host:\w\007\] +# simple command prompt +PS1=' --- [\w] --- -\u@$host: $CURSOR '" +\u@\h % ' + # customize path -for dir in $HOME/bin $HOME/.cabal/bin $HOME/perl5/perlbrew/bin /usr/local/bin /usr/local/sbin /usr/sbin; do +for dir in $HOME/bin /usr/local/bin /usr/local/sbin /usr/sbin; do if test -d $dir; then PATH=$PATH:$dir fi done export PATH -# global env vars -EDITOR=vim - # history options HISTFILESIZE=1000000 HISTSIZE=1000000 @@ -125,7 +127,7 @@ HISTCONTROL=ignoreboth HISTIGNORE='ls:bg:fg:history' HISTTIMEFORMAT='%F %T ' -export EDITOR PROMPT_COMMAND PATH LESSCHARSET GREP_OPTIONS HISTFILE HISTFILESIZE HISTSIZE HISTCONTROL HISTIGNORE HISTTIMEFORMAT INPUTRC +export EDITOR PS1 PATH LESSCHARSET GREP_OPTIONS HISTFILE HISTFILESIZE HISTSIZE HISTCONTROL HISTIGNORE HISTTIMEFORMAT INPUTRC # better override umask 0027 @@ -141,26 +143,10 @@ fi # bash options shopt -s cdable_vars checkhash checkwinsize histappend cmdhist -# perl brew installed? -if test -d ~/perl5; then - source ~/perl5/perlbrew/etc/bashrc -fi - -# python? -if test -e ~/.pythonrc; then - export PYTHONSTARTUP=~/.pythonrc -fi - # any local specific config? if test -e ~/.bashrc-local; then source ~/.bashrc-local fi -# rust? -if test -e /usr/local/rust/cargo/env; then - source /usr/local/rust/cargo/env - export RUSTUP_HOME=/usr/local/rust/rustup - export CARGO_HOME=/usr/local/rust/cargo -fi diff --git a/roles/pubnix/files/skel/dot.cshrc b/roles/pubnix/files/skel/dot.cshrc index c3c035d..3f39f96 100644 --- a/roles/pubnix/files/skel/dot.cshrc +++ b/roles/pubnix/files/skel/dot.cshrc @@ -7,9 +7,20 @@ alias h history 25 alias j jobs -l +alias l ls -alF alias la ls -aF alias lf ls -FA alias ll ls -lAF +alias lt ls -ltr +alias les less +alias md mkdir -p +alias .. cd .. +alias ... cd ../.. +alias .... cd ../../.. +alias ..... cd ../../../.. +alias grip egrep -i +alias which type -p + # These are normally set through /etc/login.conf. You may override them here # if wanted. diff --git a/roles/pubnix/tasks/main.yaml b/roles/pubnix/tasks/main.yaml index 1e5b3d4..9e0938c 100644 --- a/roles/pubnix/tasks/main.yaml +++ b/roles/pubnix/tasks/main.yaml @@ -29,7 +29,7 @@ src: "skel/{{ item }}" dest: "/usr/local/bastille/templates/services/{{ role_name }}/usr/share/skel/{{ item }}" loop: - - dot.bashrc + - dot.bash_profile - dot.cshrc - dot.emacs - dot.login @@ -56,11 +56,16 @@ # FIXME: loop over files and check size somehow, or always copy? use file module? -- name: copy skel files +- name: copy skel files into jail template shell: cp -r /usr/local/bastille/templates/services/{{ role_name }}/usr/share/skel /usr/local/bastille/jails/{{ role_name }}/root/etc/ - args: - creates: /usr/local/bastille/jails/{{ role_name }}/root/etc/skel + # args: + # creates: /usr/local/bastille/jails/{{ role_name }}/root/etc/skel +- name: copy user ssh keys + copy: + src: keys + dest: "/usr/local/bastille/" + # The normal ansible user module can't be used here, because we're # talking about jail users here. I tried to patch the module to # support the -R flag (https://github.com/ansible/ansible/pull/84371) diff --git a/roles/server/files/jlogin b/roles/server/files/jlogin new file mode 100644 index 0000000..08d046e --- /dev/null +++ b/roles/server/files/jlogin @@ -0,0 +1,45 @@ +#!/bin/sh + +jail=$1 +user=$2 +me=`id -u` +jexec="jexec" + +if test "$jail" = "-h"; then + echo "jlogin [jail] [user]" + exit +fi + +if test -z "$jail"; then + vars=$(jls -n | head -1) + eval $vars +fi +jid="" +jid=`jls | grep "$jail" | awk '{print $1}'` + +if test -z "$jid"; then + echo "jail $jail doesn't run!" + exit 1 +fi + +shell=/bin/csh +home=/home/$user +term=vt100 +path=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin +chroot="$j/run/$jail" + +if test -z "$user"; then + user=root + home=/root +fi + +if test -e $chroot/$home/.bashrc; then + shell=/usr/local/bin/bash +fi + +if test "$me" != "0"; then + jexec="sudo $jexec" +fi + +echo "# Logging into jail $jail with jid $jid #" +env - JAIL=$jail HOME=$home TERM=$term SHELL=$shell PATH=$path $jexec -U $user $jid $shell diff --git a/roles/user/bin/user.sh b/roles/user/bin/user.sh new file mode 100755 index 0000000..b5e0f92 --- /dev/null +++ b/roles/user/bin/user.sh @@ -0,0 +1,128 @@ +#!/bin/sh + +rootdir="" +user="" +groups="" +home="" +shell="/usr/local/bin/bash" +comment="" +action="" + +usage() { + echo "Usage: $0 -u user [-h home] [-s shell] [-g groups] [-d rootdir] [-c comment] -a action" + echo "Valid actions: present, absent, locked" + exit 1 +} + +getuid() { + local root="$1" + local user="$2" + pw $root show user "$user" -7 | cut -d: -f 3 +} + +run() { + echo $* + $* +} + +OPTIND=1 +while getopts d:u:h:g:s:c:a: opt ; do + case $opt in + d) + rootdir="$OPTARG" + ;; + u) + user="$OPTARG" + ;; + h) + home="$OPTARG" + ;; + g) + groups="$OPTARG" + ;; + s) + shell="$OPTARG" + ;; + c) + comment="$OPTARG" + ;; + a) + action="$OPTARG" + ;; + *) + usage + ;; + esac +done + +shift $(($OPTIND - 1)) + +if test -z "$user" -o -z "$action"; then + usage +fi + +args="" +root="" + +if test -n "$rootdir"; then + root="-R $rootdir" +fi + +if test -n "$groups"; then + args="-G $groups" +fi + +if test -n "$home"; then + args="$args -d $home -k /etc/skel -m -M 700" +else + args="$args -d /home/$user -k /etc/skel -m -M 700" +fi + +if test -n "$shell"; then + args="$args -s $shell" +else + args="$args -s /usr/local/bin/bash" +fi + +if test -n "$comment"; then + args="$args -c $comment" +fi + +case "$action" in + present) + set -x + if pw $root user show "$user" > /dev/null 2>&1; then + if pw $root user show "$user" | grep -q LOCKED; then + run pw unlock "$user" + else + echo "$user exists." + fi + else + run pw $root user add "$user" $args + fi + + if test -e "/usr/local/bastille/keys/$user" -a ! -e "/home/$user/.ssh/authorized_keys"; then + uid=$(getuid "$root" "$user") + install -m 700 -o "$uid" -g "$uid" -d "/home/$user/.ssh" + install -m 600 -o "$uid" -g "$uid" "/usr/local/bastille/keys/$user" "/home/$user/.ssh/authorized_keys" + fi + set +x + ;; + absent) + if pw $root user show "$user" > /dev/null 2>&1; then + run pw $root user del "$user" + fi + ;; + locked) + if pw $root user show "$user" > /dev/null 2>&1; then + if pw $root user show "$user" | grep -q LOCKED; then + echo "$user is already locked." + else + run pw lock "$user" + fi + fi + ;; + *) + usage + ;; +esac diff --git a/roles/user/files/keys/tom b/roles/user/files/keys/tom new file mode 100644 index 0000000..5b87e0e --- /dev/null +++ b/roles/user/files/keys/tom @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCfY4Oxp6LnFvdAOhs2hcFmQ31VyMPQmg4/6eU0LaNioroK8iniGdfM1zw48uTKApD2z5iI8SCOae7VZaab9rWwz+BExpFRYMR013quWY89gie6HK7wa2lrKt4wuKsl26HwcWOwo1dCnxKRbVqSRWUCAm4D7iArUl7+9y/VqQIZWIVPyfiqRGPZ68wCMm/VvkZggE2No2XINbVd+Ts1ddOudRpeg2BHiYZ48JWLWlnMNiJAgVQEFaBemdj9OBt9ey81/iWGbGoPeUW113SuOgNL+YLwo2pcgeMHcwC+B184LcMdt1r2O4jsW7OemLfrazq2p3VfSdzOduVDQvdGsnqpFArHgM+kPFt4YIdn772lrlMkxSgK2mbCbSzNZoomdCyuwKUt6dA3b1PZF8L6uMJK7DOVGcmrjk9UUW/goZhg6Xw0tBxYYQlhVNyRTZNwUtqC8CTJ1/xUSEqzbRO2jOxWTJFrLFJPMr0FSrwFqfFN/1DMFa4Pqb+w5OTyfKS0usikpvFoE3Ct/MQkgb1YdFseui2ARpo7SgFD/t7plYb3FLJpP49gIgK3dg8g/uiFLwwbGE13hUrzagAKChmhgfbY/yhrc+ES3OZJExleXUhYD4CCTiYjghNoYcmW2+X6c1VbOULDCrDfCRErFBW2lPVsoRebd8B30SC8YeaHzmWFdQ== scip@tripod diff --git a/roles/user/tasks/main.yaml b/roles/user/tasks/main.yaml new file mode 100644 index 0000000..40ba4a9 --- /dev/null +++ b/roles/user/tasks/main.yaml @@ -0,0 +1,19 @@ +--- + +- name: copy user ssh keys + copy: + src: keys + dest: "/usr/local/bastille/" + +# The normal ansible user module can't be used here, because we're +# talking about jail users here. I tried to patch the module to +# support the -R flag (https://github.com/ansible/ansible/pull/84371) +# but it makes no sense. Every single function needs to be patched so +# that it works for jails. +# +# So, instead I'm just using this simple script, which does the job as +# well. +- name: Manage users + loop: "{{ users }}" + ansible.builtin.script: "bin/user.sh -u {{ item.name }} -g '{{ item.groups }}' -c {{ role_name }}-user -a {{ item.state }} -d /usr/local/bastille/jails/pubnix/root" +