general fixes
[distro-setup] / brc2
diff --git a/brc2 b/brc2
index eae5aa93439b60f921cc061cacee567cf47d2c1f..6ac51839640d6b111de332c2196a89468ff154f4 100644 (file)
--- a/brc2
+++ b/brc2
@@ -172,7 +172,7 @@ slemacs() {
 
 sle() { # sl emacs
   local f=/home/iank/.emacs.d/init.el
 
 sle() { # sl emacs
   local f=/home/iank/.emacs.d/init.el
-  sl --sl-test-cmd ". /etc/os-release ; printf %s \${VERSION//[^a-zA-Z0-9]/}; test -e $f && stat -c%Y $f" --sl-test-hook slemacs "$@"
+  sl --sl-test-cmd "sed -rn '/^VERSION=/{s/^.*=//;s/[^[:alnum:]]//gp}' /etc/os-release; test -e $f && stat -c%Y $f" --sl-test-hook slemacs "$@"
 }
 ccomp ssh sle
 
 }
 ccomp ssh sle
 
@@ -441,7 +441,7 @@ ralerts() { # remote alerts
 ap() {
   # pushd in case current directory has an ansible.cfg file
   pushd /a/xans >/dev/null
 ap() {
   # pushd in case current directory has an ansible.cfg file
   pushd /a/xans >/dev/null
-  ansible-playbook -v -l ${1:- $(hostname -f)} site.yml
+  ansible-playbook -v -i ${1:- $(hostname -f)}, site.yml
   popd >/dev/null
 }
 aw() {
   popd >/dev/null
 }
 aw() {
@@ -1504,7 +1504,6 @@ btrbk-host-debug() {
 
 # $ dig ns1.gnu.org @b0.org.afilias-nst.org.
 
 
 # $ dig ns1.gnu.org @b0.org.afilias-nst.org.
 
-# todo: make sm pull/push use systemd instead of the journal cat command
 bbk() { # btrbk wrapper
   local ret=0
   c /
 bbk() { # btrbk wrapper
   local ret=0
   c /
@@ -1855,7 +1854,13 @@ dsign() {
 # set day start for use in other programs.
 # expected to do be in a format like 830, or 800 or 1300.
 ds() {
 # set day start for use in other programs.
 # expected to do be in a format like 830, or 800 or 1300.
 ds() {
+  local regex
+  regex='[0-9]?[0-9]?[0-9][0-9]'
   if [[ $1 ]]; then
   if [[ $1 ]]; then
+    if [[ ! $1 =~ $regex ]]; then
+      echo "ds: error. expected \$1 to match $regex, got \$1: $1"
+      return 1
+    fi
     echo $1 >/b/data/daystart
   else
     cat /b/data/daystart
     echo $1 >/b/data/daystart
   else
     cat /b/data/daystart
@@ -1998,8 +2003,8 @@ apache-header() {
 # https://www.gnu.org/licenses/license-recommendations.en.html. They
 # recommend that small programs, < 300 lines, be licensed under the
 # Apache License 2.0. This file contains or is part of one or more small
 # https://www.gnu.org/licenses/license-recommendations.en.html. They
 # recommend that small programs, < 300 lines, be licensed under the
 # Apache License 2.0. This file contains or is part of one or more small
-# programs. If a small program grows beyond 300 lines, I plan to switch
-# its license to GPL.
+# programs. If a small program grows beyond 300 lines, I plan to change
+# to a recommended GPL license.
 
 # Copyright 2024 Ian Kelling
 
 
 # Copyright 2024 Ian Kelling
 
@@ -2638,17 +2643,28 @@ wgkey() {
 
 host-info-all() {
   host-info-update
 
 host-info-all() {
   host-info-update
+
   bindpushb8
   bindpushb8
+  # for wireguard configs
+  ssh iank@li.b8.nz conflink
   wrt-setup
 }
 
 
   wrt-setup
 }
 
 
-# if you change a host's ip, then run
-# bindpushb8
-# wrt-setup
+
+
+
+## for updating host info like ip, location, update /p/c/host-info and
+## host_info below. the host_info array should probably be in its own
+## file that gets sourced so that it can be more easily updated.
+
+# todo: this is so long that it becomes confusing,
+# try to split it up.
+#
+# To make some changes take effect, run host-info-all.
 host-info-update() {
 
 host-info-update() {
 
-  local -A vpn_ips host_ips host_macs nonvpn_ips all_ips
+  local -A vpn_ips host_ips host_macs portfw_ips nonvpn_ips all_ips
   local -a root_hosts nonroot_hosts
 
   # the hosts with no mac
   local -a root_hosts nonroot_hosts
 
   # the hosts with no mac
@@ -2677,6 +2693,7 @@ host-info-update() {
 
     all_ips[$host]=$ip
     if $vpn; then
 
     all_ips[$host]=$ip
     if $vpn; then
+      portfw_ips[$host]=$ip
       vpn_ips[$host]=$ip
     else
       nonvpn_ips[$host]=$ip
       vpn_ips[$host]=$ip
     else
       nonvpn_ips[$host]=$ip
@@ -2686,12 +2703,15 @@ host-info-update() {
       # hosts is that it is for the User part, the IdentityFile part is
       # redundant to *.b8.nz. Also note ${host}i, we only setup those for vpn hosts, but there is no harm in overspecifying here.
       root_hosts+=($host ${host}i $host.b8.nz ${host}i.b8.nz)
       # hosts is that it is for the User part, the IdentityFile part is
       # redundant to *.b8.nz. Also note ${host}i, we only setup those for vpn hosts, but there is no harm in overspecifying here.
       root_hosts+=($host ${host}i $host.b8.nz ${host}i.b8.nz)
+      root_hosts_a[$host]=t  # a for associative array
     else
       nonroot_hosts+=($host ${host}i)
     fi
     else
       nonroot_hosts+=($host ${host}i)
     fi
-
     host_ips[$host]=$ip
     host_ips[$host]=$ip
-    host_macs[$host]=$mac
+    if [[ $mac ]]; then
+      host_macs[$host]=$mac
+    fi
+
   done </p/c/host-info
 
   {
   done </p/c/host-info
 
   {
@@ -2707,10 +2727,8 @@ EOF
     for host in ${!vpn_ips[@]}; do
       ipsuf=${vpn_ips[$host]}
       cat <<EOF
     for host in ${!vpn_ips[@]}; do
       ipsuf=${vpn_ips[$host]}
       cat <<EOF
-Host ${host}i
-Hostname b8.nz
+Host ${host}i ${host}i.b8.nz
 Port $((2200 + ipsuf))
 Port $((2200 + ipsuf))
-
 EOF
     done
 
 EOF
     done
 
@@ -2721,25 +2739,27 @@ Host $host ${host}i $host.b8.nz ${host}i.b8.nz
 HostKeyAlias $host.b8.nz
 EOF
     done
 HostKeyAlias $host.b8.nz
 EOF
     done
-  } | cedit /p/c/subdir_files/.ssh/config || [[ $? == 1 ]]
+  } | cedit -e /p/c/subdir_files/.ssh/config-static
 
   {
 
   {
-    echo "cat <<EOF"
+    # hack to please emacs parser
+    here_begin="cat <<EOF"
+    echo "$here_begin"
     for host in ${!vpn_ips[@]}; do
       ipsuf=${vpn_ips[$host]}
       i_port=$(( 2200 + ipsuf ))
       cat <<EOF
 config redirect
     for host in ${!vpn_ips[@]}; do
       ipsuf=${vpn_ips[$host]}
       i_port=$(( 2200 + ipsuf ))
       cat <<EOF
 config redirect
- option name ssh$host
- option src              wan
- option src_dport        $i_port
- option dest_port        22
- option dest_ip          \$l.$ipsuf
- option dest             lan
+option name ssh$host
+option src              wan
+option src_dport        $i_port
+option dest_port        22
+option dest_ip          \$l.$ipsuf
+option dest             lan
 config rule
 config rule
- option src              wan
- option target           ACCEPT
- option dest_port        $i_port
+option src              wan
+option target           ACCEPT
+option dest_port        $i_port
 EOF
     done
     echo "EOF"
 EOF
     done
     echo "EOF"
@@ -2751,12 +2771,17 @@ EOF
   # shellcheck disable=SC2016 # shellcheck doesnt know this is sed
   sedi '/edits below here are made automatically/,$d' /p/c/machine_specific/li/filesystem/etc/wireguard/wgmail.conf
   for host in ${!vpn_ips[@]}; do
   # shellcheck disable=SC2016 # shellcheck doesnt know this is sed
   sedi '/edits below here are made automatically/,$d' /p/c/machine_specific/li/filesystem/etc/wireguard/wgmail.conf
   for host in ${!vpn_ips[@]}; do
-    if [[ ${root_ips[$host]} ]]; then
-      # root machines dont run transmission
+    if [[ ${root_hosts_a[$host]} ]]; then
+      # root machines dont actually need vpn, but
+      # the classification still helps with other
+      # configurations.
       continue
     fi
     ipsuf=${vpn_ips[$host]}
     wghole $host $ipsuf
       continue
     fi
     ipsuf=${vpn_ips[$host]}
     wghole $host $ipsuf
+    u /b/ds/machine_specific/li/filesystem/etc/openvpn/client-config-hole/$host <<EOF
+ifconfig-push 10.5.5.${vpn_ips[$host]} 255.255.255.0
+EOF
     u /a/bin/ds/machine_specific/$host/filesystem/etc/systemd/system/openvpn-client-tr@.service <<EOF
 [Unit]
 Description=OpenVPN tunnel for %I
     u /a/bin/ds/machine_specific/$host/filesystem/etc/systemd/system/openvpn-client-tr@.service <<EOF
 [Unit]
 Description=OpenVPN tunnel for %I
@@ -2809,13 +2834,14 @@ EOF
 
   {
     echo "cat <<EOF"
 
   {
     echo "cat <<EOF"
-    for host in ${!host_ips[@]}; do
+    for host in ${!host_macs[@]}; do
       ipsuf=${host_ips[$host]}
       echo "dhcp-host=${host_macs[$host]},set:$host,\$l.$ipsuf,$host"
     done
     echo "EOF"
   } | u /p/c/dnsmasq-data
 
       ipsuf=${host_ips[$host]}
       echo "dhcp-host=${host_macs[$host]},set:$host,\$l.$ipsuf,$host"
     done
     echo "EOF"
   } | u /p/c/dnsmasq-data
 
+
   b8_ip=$(dig +short b8.nz @iankelling.org | tail -1)
   if [[ ! $b8_ip ]]; then
     echo "$0: error: got empty b8.nz ip. returning 1"
   b8_ip=$(dig +short b8.nz @iankelling.org | tail -1)
   if [[ ! $b8_ip ]]; then
     echo "$0: error: got empty b8.nz ip. returning 1"
@@ -2834,37 +2860,131 @@ $host  A       10.2.0.$ipsuf
 ${host}wg      A       10.8.0.$ipsuf
 ${host}vp      A       10.5.5.$ipsuf
 ${host}tr      A       10.174.$ipsuf.2
 ${host}wg      A       10.8.0.$ipsuf
 ${host}vp      A       10.5.5.$ipsuf
 ${host}tr      A       10.174.$ipsuf.2
+${host}i       A       $b8_ip
 EOF
     done
 EOF
     done
-  } | cedit vpn-ips-update /p/c/machine_specific/vps/bind-initial/db.b8.nz ||:
+  } | cedit -e vpn-ips-update /p/c/machine_specific/vps/bind-initial/db.b8.nz
 
 
   echo checking for stray files:
 
   initial_dir="$PWD"
 
 
   echo checking for stray files:
 
   initial_dir="$PWD"
-  cd /a/bin/ds/machine_specific
-  ngset
-  files=( */filesystem/etc/systemd/system/openvpn-client-tr@.service )
-  ngreset
-  cd "$initial_dir"
+  while read -r dir path; do
+    cd $dir
+    ngset
+    files=( */$path )
+    ngreset
+    cd "$initial_dir"
+    for f in "${files[@]}"; do
+      host=${f%%/*}
+      if [[ ! ${vpn_ips[$host]} ]]; then
+        e rm $dir/$f
+      fi
+    done
+  done <<'EOF'
+/a/bin/ds/machine_specific filesystem/etc/systemd/system/openvpn-client-tr@.service
+/p/c/machine_specific filesystem/etc/wireguard/wghole.conf
+EOF
+
+  files=( /b/ds/machine_specific/li/filesystem/etc/openvpn/client-config-hole/* )
   for f in "${files[@]}"; do
   for f in "${files[@]}"; do
-    host=${f%%/*}
+    host=${f##*/}
     if [[ ! ${vpn_ips[$host]} ]]; then
     if [[ ! ${vpn_ips[$host]} ]]; then
-      e rm /a/bin/ds/machine_specific/$host/filesystem/etc/systemd/system/openvpn-client-tr@.service
+      e rm $f
+      e ssh root@li.b8.nz rm -f $f
     fi
   done
 
     fi
   done
 
-  cd /p/c/machine_specific
-  ngset
-  files=( */filesystem/etc/wireguard/wghole.conf )
-  ngreset
-  cd $initial_dir
-  for f in "${files[@]}"; do
-    host=${f%%/*}
-    if [[ ! ${vpn_ips[$host]} ]]; then
-      e rm /p/c/machine_specific/$host/filesystem/etc/wireguard/wghole.conf
+  tmpf=$(mktemp)
+  {
+    printf "%s" "Host * "
+    sed -n '/^Host /h;/^IdentityFile .*\/home/{g;s/^Host//;s/ / !/gp}' /p/c/subdir_files/.ssh/config-static | tr '\n' ' '
+    echo
+    echo "IdentityFile ~/.ssh/work"
+  } >$tmpf
+  cedit -e work-identity /p/c/subdir_files/.ssh/config-static <$tmpf
+  rm -f $tmpf
+
+  ### begin focus on hosts file update ###
+  #
+  # This started as its own function, but it actually
+  # needed to alter the ssh config, so combined it.
+  #
+  # background: This is finally doing dynamic ip resolution via the hosts
+  # file. I considered detecting where each host was dynamically or
+  # something, but ultimately decided to mostly avoid that, other than
+  # detecting the status of the current machine I'm on.  I want to be able
+  # to move it around without having to manually type much of anything.
+  local -a host_domain_suffix hosts
+  local -A ip_to_hosts
+  local suf ip i host at_home suf_from_here
+
+  source /p/c/domain-info
+
+  at_home=false
+  if ip n | grep -q "10.2.0.1 .* b4:75:0e:fd:06:4a"; then
+    at_home=true
+  fi
+
+  for i in ${host_domain_suffix[@]}; do
+    if [[ $i == *.* ]]; then
+      suf=$i
+      continue
+    fi
+    hosts+=($i)
+    if [[ $i == "$HOSTNAME" ]]; then
+      unset "portfw_ips[$i]"
+      continue
+    fi
+
+    suf_from_here=$suf
+    if ! $at_home && [[ $suf == .b8.nz || $suf == [wc].b8.nz ]]; then
+      suf_from_here=i.b8.nz
+    else
+      unset "portfw_ips[$i]"
     fi
     fi
+
+    ip=$(getent ahostsv4 "$i$suf_from_here" | awk '{ print $1 }' | head -n1) ||:
+    if [[ ! $ip ]]; then
+      if [[ $suf == .office.fsf.org ]]; then
+        suf_from_here=wg.b8.nz
+        ip=$(getent ahostsv4 "$i$suf_from_here" | awk '{ print $1 }' | head -n1) ||:
+      fi
+      if [[ ! $ip ]]; then
+        echo error: failed to get ip of "$i$suf_from_here"
+        return 1
+      fi
+    fi
+    ip_to_hosts[$ip]+=" $i"
   done
   done
+
+  for ip in "${!ip_to_hosts[@]}"; do
+    echo "$ip${ip_to_hosts[$ip]}"
+  done | s cedit -e hosts-file-up /etc/hosts
+  for host in ${hosts[@]}; do
+    echo $host
+  done >/p/c/subdir_files/.dsh/group/btrbk
+  ### end focus on hosts file update ###
+
+
+  # note: note sure if this is a great way to check.
+  # todo: think about it
+
+  if $at_home; then
+    # possible that in the future we want to create
+    # a dynamic file here, and then we can move the cat
+    # command above out of the conditional
+    rsync -a /p/c/subdir_files/.ssh/config-static ~/.ssh/config
+  else
+    for host in ${!portfw_ips[@]}; do
+      ipsuf=${portfw_ips[$host]}
+      cat <<EOF
+Host ${host}
+Port $((2200 + ipsuf))
+EOF
+    done > ~/.ssh/config-dynamic
+    cat /p/c/subdir_files/.ssh/config-static ~/.ssh/config-dynamic  >~/.ssh/config
+  fi
 }
 
 # usage host ipsuf [extrahost]
 }
 
 # usage host ipsuf [extrahost]
@@ -3264,8 +3384,8 @@ myprof() {
   pushd /home/iank/.local/share/profanity/chatlogs/iank_at_fsf.org/rooms/office_at_conference.fsf.org
   logs=(*)
   logcount=${#logs[@]}
   pushd /home/iank/.local/share/profanity/chatlogs/iank_at_fsf.org/rooms/office_at_conference.fsf.org
   logs=(*)
   logcount=${#logs[@]}
-  if (( logcount > 15 )); then
-    i=$(( logcount - 15 ))
+  if (( logcount > 16 )); then
+    i=$(( logcount - 16 ))
   else
     i=0
   fi
   else
     i=0
   fi
@@ -4652,6 +4772,23 @@ tclear() {
   done
 }
 
   done
 }
 
+opensslcertinfo() {
+  openssl x509 -txt -in "$@"
+}
+
+# dsh on btrbk hosts
+dsb() {
+:
+  }
+
+# dsh a file and run it
+dsa() {
+  local ret file
+  if ! parallel -j 10 scp x {}:/tmp <~/.dsh/group/btrbk; then
+    echo parallel scp failed. dsa returning $ret
+    fi
+  dsh -g btrbk
+  }
 
 export BASEFILE_DIR=/a/bin/fai-basefiles
 
 
 export BASEFILE_DIR=/a/bin/fai-basefiles