| @@ -0,0 +1,155 @@ | |||||
| Embedded Lab 1 | |||||
| ============== | |||||
| This is the configuration and setup information for the lab. | |||||
| Settings | |||||
| -------- | |||||
| The file `settings.conf` contains the various variables to use. | |||||
| ### Misc | |||||
| - labuser - The user that can modify the database, and is used to login | |||||
| for generating API Keys. | |||||
| - labuserzfs - The root ZFS FS for which user data will be stored. This | |||||
| is where board clones will be made, i.e. $labuserzfs/$user/$board. A | |||||
| proper user quota should be set on this FS. | |||||
| - ifacebridge - The bridge interface to add the epair interface for network | |||||
| - devfsdefaultruleset - The base devfs ruleset that all jails start with. | |||||
| ### Directories | |||||
| - labhome - Home directory where state information about the lab is kept. | |||||
| This includes things like the database for the API, ssh keys, etc. | |||||
| - labbin - Directory where the binaries and scripts live. This is where | |||||
| the `settings.conf` file exists, and the scripts like setting up the | |||||
| jail, and deploying the ssh keys. Simply, where this repository is | |||||
| located. | |||||
| - userzfsmount - The directory that the ZFS dataset labuserzfs is mounted | |||||
| at. When doing operations like populating jails, or creating them, this | |||||
| is the directory that should be used. | |||||
| ### Resource Dirs | |||||
| These list the various resources used/allocated by the system. The | |||||
| directory contains directories where the name is the value of the | |||||
| resource. Directories are used because posix guarantees atomic | |||||
| create/delete of directories, ensuring that an error occures if the | |||||
| operation fails. | |||||
| - devfsruleresourcedir - This is the set of devfs rules. | |||||
| - ipresourcedir - This is the set of IP addresses available. | |||||
| ### Scripts | |||||
| - keygencmd - Command used to generate a key for the specified user, and | |||||
| add it to the database. | |||||
| ### Data files | |||||
| - labkeys - File that contains lines of "<user> <ssh public key>". This | |||||
| is used by update_authkeys.sh to populate labauthfile (aka | |||||
| authorized_keys). | |||||
| - db_file - SQLite3 database file that contains API keys and other | |||||
| information. | |||||
| ### Internal | |||||
| - labuid - This is 742, and is used by the setup script. It should not | |||||
| be modified. | |||||
| Misc Files | |||||
| ---------- | |||||
| `base_setup.sh`: Script to setup a base image w/ various defaults | |||||
| `board_conf.ucl`: UCL configuration file for the embedded lab daemon | |||||
| `board_script`: Script that is run by the daemon, that reserves and | |||||
| releases the specific board. It allocates resources (such as local | |||||
| IP address) and launches the jail, and when the board is released, | |||||
| it frees up the various resources. | |||||
| `create_resource`: Script used by `setup_resources.sh` to initalize | |||||
| the various resources when this is first configured. | |||||
| `keygen`: Script for generating a new API key for the specified user. | |||||
| This is used by the `update_authkeys.sh` script. | |||||
| `rc.conf.template`: Template `rc.conf` for jails. | |||||
| `setup_lab.sh`: Script to setup the machine for the first time to run | |||||
| the lab. | |||||
| `setup_resources.sh`: Script to setup initial resources. | |||||
| `test.*`: File and script to test that `board_script` does what is | |||||
| expected. | |||||
| `update_authkeys.sh`: A script used to generate the `authorized_keys` | |||||
| file. The input is a file with each line containing the user followed | |||||
| by their ssh-key. It will restrict that key to run the `keygen` script | |||||
| to get the user an API key. | |||||
| SNMP | |||||
| ---- | |||||
| SNMP is used to control a PoE switch which provides power to various | |||||
| boards. NetSNMP is used. It requires a little bit of setup. First is | |||||
| to set the default version to 3. Despite v1 being more common, v3 | |||||
| provides better security. | |||||
| ### Configure NetSNMP | |||||
| `~root/.snmp/snmp.conf`: | |||||
| ``` | |||||
| defVersion 3 | |||||
| ``` | |||||
| NetSNMP will use a file `.snmp/hosts/<hostname>.conf` to set various | |||||
| parameters. For example: | |||||
| ``` | |||||
| defVersion 3 | |||||
| defSecurityName admin | |||||
| defAuthPassphrase XXXYYYZZZ | |||||
| defAuthType SHA | |||||
| defPrivPassphrase WWWUUUVVV | |||||
| defPrivType DES | |||||
| defSecurityLevel authPriv | |||||
| transport <ip address> | |||||
| ``` | |||||
| This segments where authentication credentials are stored, and allows | |||||
| using names w/o having to enter them into a DNS server. | |||||
| ### Configure switch | |||||
| The program [vlanmang](https://www.funkthat.com/gitea/jmg/vlanmang) is | |||||
| used to maintain the configuration of the switch, most specifically | |||||
| what ports are connected to which VLAN. | |||||
| The file `data.py` contains the configuration information. It will | |||||
| read the auth methods and passwords from the NetSNMP configuration | |||||
| files setup in the previous section. | |||||
| Setup `vlanmang`: | |||||
| ``` | |||||
| ln -s ~lab/.local ~root | |||||
| python3.8 -m venv venv | |||||
| . ./venv/bin/activate | |||||
| export TMPDIR=/var/tmp | |||||
| pip install git+https://www.funkthat.com/gitea/jmg/vlanmang.git | |||||
| ``` | |||||
| Configure switches: | |||||
| ``` | |||||
| . ./venv/bin/activate | |||||
| python -m vlanmang | |||||
| ``` | |||||
| @@ -0,0 +1,21 @@ | |||||
| #!/bin/sh - | |||||
| # setup a base dir | |||||
| DESTDIR="$1" | |||||
| # copied and modified from release/tools/arm.subr | |||||
| # -w yes -> -w no | |||||
| /usr/sbin/pw -R ${DESTDIR} groupadd freebsd -g 1001 | |||||
| mkdir -p ${DESTDIR}/home/freebsd | |||||
| /usr/sbin/pw -R ${DESTDIR} useradd freebsd \ | |||||
| -m -M 0755 -w no -n freebsd -u 1001 -g 1001 -G 0 \ | |||||
| -c 'FreeBSD User' -d '/home/freebsd' -s '/bin/sh' | |||||
| /usr/sbin/pw -R ${DESTDIR} \ | |||||
| usermod root -w yes | |||||
| /usr/bin/sed -i '.bak' \ | |||||
| -e 's/#PasswordAuthentication no/PasswordAuthentication no/' \ | |||||
| -e 's/#ChallengeResponseAuthentication yes/ChallengeResponseAuthentication no/' \ | |||||
| "${DESTDIR}/etc/ssh/sshd_config" | |||||
| @@ -0,0 +1,25 @@ | |||||
| setup_script = /ztank/prog/board_script; | |||||
| classes { | |||||
| cora-z7s = { arch = arm-armv7; } | |||||
| pine64-a64-lts = { arch = arm64-aarch64; } | |||||
| } | |||||
| boards [ | |||||
| { | |||||
| name = cora-1; | |||||
| brdclass = cora-z7s; | |||||
| options = [ | |||||
| { cls = snmppower, host = poe, port = 2 }, | |||||
| ] | |||||
| }, | |||||
| { | |||||
| name = a64lts-1; | |||||
| brdclass = pine64-a64-lts; | |||||
| options = [ | |||||
| { cls = etheriface, val = awg0.103 }, | |||||
| { cls = serialconsole, val = /dev/ttyU0 }, | |||||
| { cls = snmppower, host = poe, port = 3 }, | |||||
| ] | |||||
| }, | |||||
| ] | |||||
| @@ -0,0 +1,163 @@ | |||||
| #!/bin/sh - | |||||
| # | |||||
| # Copyright (c) 2020 The FreeBSD Foundation | |||||
| # | |||||
| # This software1 was developed by John-Mark Gurney under sponsorship | |||||
| # from the FreeBSD Foundation. | |||||
| # | |||||
| # Redistribution and use in source and binary forms, with or without | |||||
| # modification, are permitted provided that the following conditions | |||||
| # are met: | |||||
| # 1. Redistributions of source code must retain the above copyright | |||||
| # notice, this list of conditions and the following disclaimer. | |||||
| # 2. Redistributions in binary form must reproduce the above copyright | |||||
| # notice, this list of conditions and the following disclaimer in the | |||||
| # documentation and/or other materials provided with the distribution. | |||||
| # | |||||
| # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
| # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
| # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
| # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
| # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
| # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
| # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
| # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
| # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| # SUCH DAMAGE. | |||||
| # | |||||
| set -e | |||||
| . $(dirname $0)/settings.conf | |||||
| cmd="$1" | |||||
| board="$2" | |||||
| user="$3" | |||||
| sshkey="$4" | |||||
| # standard globals | |||||
| jaildir="$userzfsmount/$user/$board" | |||||
| # XXX - instead, move to an allocated dir, makes cleaning up easier | |||||
| allocateresource() | |||||
| { | |||||
| resdir="$1" | |||||
| while :; do | |||||
| res="$(cd "$resdir" && ls | head -n 1)" | |||||
| if [ x"$res" = x"" ]; then | |||||
| echo "Resource allocation failure for: $resdir" | |||||
| exit 1 | |||||
| fi | |||||
| if rmdir "$resdir/$res" 2>/dev/null; then | |||||
| fsync "$resdir" | |||||
| break | |||||
| fi | |||||
| done | |||||
| echo "$res" | |||||
| } | |||||
| releaseresource() | |||||
| { | |||||
| resdir="$1" | |||||
| res="$2" | |||||
| mkdir "$resdir/$res" || exit 1 | |||||
| } | |||||
| if [ x"$cmd" = x"reserve" ]; then | |||||
| zfs clone -p "$basezfs" "$labuserzfs/$user/$board" | |||||
| if [ ! -z "$sshkey" ]; then | |||||
| mkdir -p $(dirname "$jaildir/$sshkeydest") | |||||
| echo "$sshkey" > "$jaildir/$sshkeydest" | |||||
| chown -R 1001:1001 $(dirname "$jaildir/$sshkeydest") | |||||
| chmod -R 0700 $(dirname "$jaildir/$sshkeydest") | |||||
| fi | |||||
| ip=$(allocateresource "$ipresourcedir") | |||||
| devfsrule=$(allocateresource "$devfsruleresourcedir") | |||||
| epair="$(ifconfig epair create)" | |||||
| iface="${epair%a}b" | |||||
| sed \ | |||||
| -e "s/@@BOARD@@/$board/g" \ | |||||
| -e "s/@@IP@@/$ip/g" \ | |||||
| -e "s/@@IFACE@@/$iface/g" \ | |||||
| < "$templatercconf" > "$jaildir/etc/rc.conf" | |||||
| ifconfig "$ifacebridge" addm "$epair" | |||||
| ifconfig "$epair" up | |||||
| # devfs ruleset needs work | |||||
| # allow.mount \ | |||||
| # allow.mount.devfs \ | |||||
| # enforce_statfs=1 \ | |||||
| # devfs_ruleset=10 \ | |||||
| # copy devfs rulesets from devfsdefaultruleset to devfsrule | |||||
| devfspath="$jaildir"/dev | |||||
| devfs rule -s "$devfsrule" delset | |||||
| devfs rule -s "$devfsdefaultruleset" show | devfs rule -s "$devfsrule" add - | |||||
| mount -t devfs -o ruleset="$devfsrule" devfs "$devfspath" | |||||
| jailstart=$(jail -c \ | |||||
| name="$board" \ | |||||
| path="$jaildir" \ | |||||
| vnet=new \ | |||||
| vnet.interface="$iface" \ | |||||
| exec.start="/bin/sh /etc/rc") | |||||
| # wait for ssh host keys and add them | |||||
| sshhostkeys="$(jexec "$board" cat /etc/ssh/ssh_host_*.pub)" | |||||
| # output additional attributes on reserve | |||||
| # NOTE: Make sure to update bitelab to pass these variables back. | |||||
| export ip | |||||
| export iface | |||||
| export jailstart | |||||
| export devfsrule | |||||
| export devfspath | |||||
| export sshhostkeys | |||||
| jq \ | |||||
| --arg allargs "$*" \ | |||||
| -n \ | |||||
| '{ | |||||
| allargs: $allargs, | |||||
| ip: $ENV.ip, | |||||
| iface: $ENV.iface, | |||||
| jailstart: $ENV.jailstart, | |||||
| devfsrule: $ENV.devfsrule, | |||||
| devfspath: $ENV.devfspath, | |||||
| sshhostkeys: $ENV.sshhostkeys | |||||
| }' | |||||
| elif [ x"$cmd" = x"release" ]; then | |||||
| jail -r "$board" | |||||
| umount "$devfspath" | |||||
| # epair doesn't immediate reappear, schedule it | |||||
| nohup sh -c 'for i in $(jot 5 1); do | |||||
| if ifconfig "$iface" destroy; then | |||||
| break; | |||||
| fi; | |||||
| sleep 1; | |||||
| done' > /dev/null 2>&1 & | |||||
| releaseresource "$ipresourcedir" "$ip" | |||||
| releaseresource "$devfsruleresourcedir" "$devfsrule" | |||||
| # for some reason not all jail processes are terminated, | |||||
| # need to retry | |||||
| sleep .5 | |||||
| for x in $(jot 5 1); do | |||||
| if zfs destroy "$labuserzfs/$user/$board"; then | |||||
| break | |||||
| fi | |||||
| sleep 1 | |||||
| done | |||||
| # no output on release | |||||
| fi | |||||
| @@ -0,0 +1,18 @@ | |||||
| #!/bin/sh - | |||||
| dir="$1" | |||||
| pref="$2" | |||||
| start="$3" | |||||
| stop="$4" | |||||
| if [ -z "$dir" -o -z "$start" -o -z "$stop" ]; then | |||||
| echo "Usage: $0 <dir> <prefix> <start> <stop>" >&2 | |||||
| exit 1 | |||||
| fi | |||||
| mkdir -p "$dir" | |||||
| cd "$dir" | |||||
| for i in $(jot $(($stop - $start + 1)) "$start"); do | |||||
| mkdir "$pref$i" | |||||
| done | |||||
| @@ -0,0 +1,44 @@ | |||||
| # | |||||
| # Installation information: | |||||
| # ln -s ~lab/.local ~root | |||||
| # ~/.local/bin/virtaulenv venv | |||||
| # . ./venv/bin/activate | |||||
| # export TMPDIR=/var/tmp | |||||
| # pip install git+https://www.funkthat.com/gitea/jmg/vlanmang.git | |||||
| # | |||||
| # Configuration information: | |||||
| # . ./venv/bin/activate | |||||
| # python -m vlanmang | |||||
| # | |||||
| import vlanmang | |||||
| from pysnmp.hlapi import usmDESPrivProtocol | |||||
| protomapping = dict(DES=usmDESPrivProtocol) | |||||
| def parse_snmpconf(fname): | |||||
| snmpconf = {} | |||||
| with open(fname) as fp: | |||||
| snmpconf = dict((l.strip().split() for l in fp if l.strip())) | |||||
| return snmpconf | |||||
| def make_vlanswitch(fname, switch_info, *args): | |||||
| snmpconf = parse_snmpconf(fname) | |||||
| authdata = dict(username=snmpconf['defSecurityName'], authKey=snmpconf['defAuthPassphrase'], | |||||
| privKey=snmpconf['defPrivPassphrase'], privProtocol=protomapping[snmpconf['defPrivType']]) | |||||
| switch = vlanmang.SwitchConfig(snmpconf['transport'], authdata, switch_info, *args) | |||||
| return switch | |||||
| switch = { | |||||
| 1: { | |||||
| 'u': [ 1, 24 ], | |||||
| } | |||||
| } | |||||
| for i in range(2, 24): | |||||
| switch[i + 100] = dict(t=[ 1 ], u=[ i ]) | |||||
| switch = make_vlanswitch('/root/.snmp/hosts/poe.conf', switch, list(range(25, 36))) | |||||
| @@ -0,0 +1,43 @@ | |||||
| [loggers] | |||||
| keys=root,aiosqlite,databases | |||||
| [handlers] | |||||
| keys=syslog,null | |||||
| [formatters] | |||||
| keys=simpleFormatter | |||||
| [logger_root] | |||||
| level=DEBUG | |||||
| handlers=syslog | |||||
| # Both aiosqlite and databases log sensitive info, DO NOT | |||||
| # enable logging on these unless you want to contaminate your | |||||
| # logs w/ authentication credentials and other security senstive | |||||
| # information | |||||
| [logger_aiosqlite] | |||||
| level=DEBUG | |||||
| handlers=null | |||||
| qualname=aiosqlite | |||||
| propagate=0 | |||||
| [logger_databases] | |||||
| level=DEBUG | |||||
| handlers=null | |||||
| qualname=databases | |||||
| propagate=0 | |||||
| [handler_null] | |||||
| class=NullHandler | |||||
| [handler_syslog] | |||||
| class=handlers.SysLogHandler | |||||
| level=NOTSET | |||||
| formatter=simpleFormatter | |||||
| args=('/var/run/log', handlers.SysLogHandler.LOG_USER) | |||||
| [formatter_simpleFormatter] | |||||
| format=bitelab: %(asctime)s.%(msecs)03d - %(name)s - %(levelname)s - %(message)s | |||||
| datefmt=%Y-%m-%dT%H:%M:%S | |||||
| # XXX This doesn't appear to work | |||||
| #converter=time.gmtime | |||||
| @@ -0,0 +1,2 @@ | |||||
| :programname, isequal, "bitelab" | |||||
| *.* /ztank/state/bitelab.log | |||||
| @@ -0,0 +1,16 @@ | |||||
| #!/bin/sh - | |||||
| user="$1" | |||||
| . $(dirname $0)/settings.conf | |||||
| umask 077 | |||||
| key="$(LC_ALL=C tr -c -d 'a-z0-9' < /dev/random | dd bs=1 count=50 2>/dev/null)" | |||||
| python3.8 -c 'import hashlib; import sqlite3; import sys; db = sqlite3.connect(sys.argv[1]); db.execute("insert into apikeys (user, key) values (?, ?)", (sys.argv[2], hashlib.blake2s(sys.argv[3].encode()).hexdigest())); db.commit(); db.close()' "$db_file" "$1" "$key" | |||||
| #echo "$1 $key" >> "$apikeyfile" | |||||
| echo "Your API key is: $key" | |||||
| exit 0 | |||||
| @@ -0,0 +1,8 @@ | |||||
| hostname="@@BOARD@@" | |||||
| ifconfig_@@IFACE@@="@@IP@@" | |||||
| sshd_enable="YES" | |||||
| defaultrouter="172.30.15.1" | |||||
| sendmail_enable="NONE" | |||||
| sendmail_submit_enable="NO" | |||||
| sendmail_outbound_enable="NO" | |||||
| sendmail_msp_queue_enable="NO" | |||||
| @@ -0,0 +1,28 @@ | |||||
| # misc | |||||
| labuser="lab" | |||||
| labuserzfs="ztank/user" | |||||
| basezfs="ztank/base/13-current@r366088" | |||||
| sshkeydest="home/freebsd/.ssh/authorized_keys" | |||||
| ifacebridge="bridge0" | |||||
| devfsdefaultruleset="10" | |||||
| # dirs | |||||
| labhome="/ztank/state" | |||||
| labbin="/ztank/prog" | |||||
| userzfsmount="/ztank/user" | |||||
| # resource dirs | |||||
| ipresourcedir="${labhome}/ips" | |||||
| devfsruleresourcedir="${labhome}/devfsrules" | |||||
| # scripts | |||||
| keygencmd="$labbin/keygen" | |||||
| # data files | |||||
| labkeys="$labhome/lab_keys" | |||||
| labauthfile="$labhome/.ssh/authorized_keys" | |||||
| db_file="$labhome/bitelab.sqlite" | |||||
| templatercconf="$labbin/rc.conf.template" | |||||
| # Values that should not be customized | |||||
| labuid="742" | |||||
| @@ -0,0 +1,30 @@ | |||||
| #!/bin/sh - | |||||
| # | |||||
| # Script to setup the environment | |||||
| # | |||||
| . $(dirname $0)/settings.conf | |||||
| if ! id $labuser > /dev/null 2>&1; then | |||||
| # create the user and group | |||||
| echo setting up accounts... | |||||
| pw groupadd "$labuser" -g "$labuid" | |||||
| # /bin/sh is required for commands specified in authorized_keys to run | |||||
| pw useradd "$labuser" -u "$labuid" -c "Embedded Lab User" \ | |||||
| -d "$labhome" -g "$labuid" -s "/bin/sh" | |||||
| else | |||||
| echo accounts already setup... | |||||
| fi | |||||
| echo 'setting permissions...' | |||||
| chown "$labuser" "$labhome" | |||||
| if ! zfs list "$labuserzfs" 2>/dev/null; then | |||||
| zfs create "$labuserzfs" | |||||
| fi | |||||
| # XXX - decide how to do ZFS quotas | |||||
| # even if a user quota was generic (it isn't), w/ the datasets | |||||
| # being root owned, a flat quota for "$labuserzfs/$user" seems | |||||
| # to make the most sense | |||||
| @@ -0,0 +1,7 @@ | |||||
| #!/bin/sh - | |||||
| . $(dirname $0)/settings.conf | |||||
| ${labbin}/create_resource "$ipresourcedir" 172.30.15. 50 100 | |||||
| ${labbin}/create_resource "$devfsruleresourcedir" "" 50 100 | |||||
| @@ -0,0 +1,8 @@ | |||||
| { | |||||
| "allargs": "reserve cora-1 jmg ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7idUEks/3mCWne1iEzLN8URpnbiXqas3fz2T4NwDj2eNtofzzwDdP3SWiPghtmqB840jUl47Nsujuwz6stpUUpNtKVDF2V9ziMS/rlTTXAxvQxUdPtiCtdHW+niXedksf/yDq0CQTxATSj4aNnfq34JHlPc0fkaMDaYqSPERJ9JKlt5NxBpw2xQ0S5itX9SHn6zMWUw1VxyZxU8dxi1g0FuLAhMgkXyWpcBTBx7nuuKI1FjlB7TKAhQeoxRZGTDsGrFDxpIf8MbYi8Bg8ljLZFi2mUrf8+HVV7z6qQdOFu1BmfuJQI63ZidrZdh3Y7zoBdJrXEMLsAdoVe8k/xHBf", | |||||
| "ip": "172.30.15.100", | |||||
| "iface": "epair0b", | |||||
| "jailstart": "Setting hostname: cora-1.\nELF ldconfig path: /lib /usr/lib /usr/lib/compat\nStarting Network: lo0 epair0b.\nlo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384\n\toptions=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>\n\tinet6 ::1 prefixlen 128\n\tinet6 fe80::1%lo0 prefixlen 64 scopeid 0x1\n\tinet 127.0.0.1 netmask 0xff000000\n\tgroups: lo\n\tnd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>\nepair0b: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500\n\toptions=8<VLAN_MTU>\n\tether 02:77:fc:66:d9:0b\n\tinet 172.30.15.100 netmask 0xffff0000 broadcast 172.30.255.255\n\tgroups: epair\n\tmedia: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)\n\tstatus: active\n\tnd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>\nadd host 127.0.0.1: gateway lo0 fib 0: route already in table\nadd net default: gateway 172.30.15.1\nadd host ::1: gateway lo0 fib 0: route already in table\nadd net fe80::: gateway ::1\nadd net ff02::: gateway ::1\nadd net ::ffff:0.0.0.0: gateway ::1\nadd net ::0.0.0.0: gateway ::1\nUpdating /var/run/os-release done.\nCreating and/or trimming log files.\nUpdating motd:.\nClearing /tmp (X related).\nStarting syslogd.\nGenerating RSA host key.\n2048 SHA256:ZIe0QWoQwjA+z2aRWXRTgjrXRH82zQcmM9tUObkt6KI root@cora-1 (RSA)\nGenerating ECDSA host key.\n256 SHA256:L+/oYNOqCpRtUoQ3mePm7xCQ3RCWG4k5QKaflfqoY/U root@cora-1 (ECDSA)\nGenerating ED25519 host key.\n256 SHA256:3UFoFyfWdwOD2SAXf1eumyqYT4vmgKR6AdrFOKemtbU root@cora-1 (ED25519)\nPerforming sanity check on sshd configuration.\nStarting sshd.\nStarting cron.\n\nWed Dec 2 01:51:00 UTC 2020", | |||||
| "devfsrule": "100", | |||||
| "sshhostkeys": "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPb6VZJBJJ98/TPW95w2SODbkjrg/6ilRdY5TdR1PZW2kB7QAvp/NpY97wXVZQ5yIgXmk4z1gEpQOPt3MREhZy0= root@cora-1\nssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICLL2Zm5BzMd+Y6Lt2xI+z6BndD2PCS+/zQxrNjdSe30 root@cora-1\nssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCqo9Rn2R9Dl97jXEHSgx6Sz0r+mD40m7nVcQPcX2F+uDeJB3KXvF+ixNBMMpiXes4NX2+MvlOu9g9vehNGmnnztNno8w44p4eHOwteEiV2G0cvsfSS340CiN+H3/lN0Gt4bekle7Yn8dsgGsDKSpA3ur9lkZJUlwwYBpzzVX+SASXueG3b/R8F5gxvDtBkMuydbwfjYxVc4sErRghQUfNnZpdm6pu9D8xJ5PcfnHTJaCkLD4ebMsI/eag/HRM6EE9Mq8By68QF8UWizK5TWYuTpOL0LjxoS6v/y3CAk72A1oPuRATyLZ+CrlQsU5lIyxNPwuaiB9+QuFOhfr5TIuVN root@cora-1" | |||||
| } | |||||
| @@ -0,0 +1,2 @@ | |||||
| sh /ztank/prog/board_script reserve cora-1 jmg "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7idUEks/3mCWne1iEzLN8URpnbiXqas3fz2T4NwDj2eNtofzzwDdP3SWiPghtmqB840jUl47Nsujuwz6stpUUpNtKVDF2V9ziMS/rlTTXAxvQxUdPtiCtdHW+niXedksf/yDq0CQTxATSj4aNnfq34JHlPc0fkaMDaYqSPERJ9JKlt5NxBpw2xQ0S5itX9SHn6zMWUw1VxyZxU8dxi1g0FuLAhMgkXyWpcBTBx7nuuKI1FjlB7TKAhQeoxRZGTDsGrFDxpIf8MbYi8Bg8ljLZFi2mUrf8+HVV7z6qQdOFu1BmfuJQI63ZidrZdh3Y7zoBdJrXEMLsAdoVe8k/xHBf" > test.json | |||||
| cat test.json | |||||
| @@ -0,0 +1,18 @@ | |||||
| #!/bin/sh - | |||||
| set -x | |||||
| if [ ! -f "test.json" ]; then | |||||
| echo no test jail is running | |||||
| exit 1 | |||||
| fi | |||||
| json="$(cat test.json)" | |||||
| keys=$(echo "$json" | jq --raw-output 'keys[]') | |||||
| for i in $keys; do | |||||
| eval export $i='$(echo "$json" | jq --raw-output .[\"$i\"])' | |||||
| done | |||||
| sh -x ./board_script release cora-1 jmg | |||||
| @@ -0,0 +1,46 @@ | |||||
| #!/bin/sh - | |||||
| . ./settings.conf | |||||
| makeauthkeys() | |||||
| { | |||||
| local inp out i | |||||
| inp="$1" | |||||
| out="$2" | |||||
| while read user keytype key; do | |||||
| echo 'restrict,command="'"$keygencmd $user"'"'" $keytype $key" | |||||
| done < "$inp" > "$out" | |||||
| } | |||||
| if [ x"$1" = x"test" ]; then | |||||
| set -e | |||||
| tmpdir=$(mktemp -d -t testfoobar) | |||||
| trap "rm -rf $tmpdir" EXIT | |||||
| labkeys="$tmpdir/lab_keys" | |||||
| echo 'someuser ssh-rsa auserkey' > "$labkeys" | |||||
| makeauthkeys "$labkeys" "$tmpdir/auth_out" | |||||
| cat "$tmpdir/auth_out" | |||||
| exit 0 | |||||
| fi | |||||
| if ! id $labuser > /dev/null 2>&1; then | |||||
| echo "ERROR: The user \"$labuser\" does not exist." | |||||
| exit 1 | |||||
| fi | |||||
| set -e | |||||
| mkdir "${labauthfile}.lock" | |||||
| trap "rmdir ${labauthfile}.lock" EXIT | |||||
| tmpfile="${labauthfile}.tmp" | |||||
| makeauthkeys "$labkeys" "$tmpfile" | |||||
| chown "$labuser:$labuser" "$tmpfile" | |||||
| mv "$tmpfile" "$labauthfile" | |||||