├── LICENSE ├── README.md ├── jmore └── jmore.6 /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2023-2024 Slawomir Wojciech Wojtczak (vermaden) 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that following conditions are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS 'AS IS' AND ANY 15 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY 18 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jmore(8) 2 | FreeBSD Jail listing and managing utility. 3 | 4 | ## FAQ 5 | 6 | ### Why `jmore(8)` name? 7 | Initially it was named `jless(8)` and below is the reasoning for that choice ... 8 | 9 | Because that is the closest thing to FreeBSD base system `jls(8)` command and it has some reference for other known `less(8)` command. 10 | 11 | But **seschwar** from `lobste.rs` page made me aware that there already is a `jless` project available - command line JSON viewer written in Rust - thank You for that. 12 | 13 | So as `less(8)` is `more(8)` and `more(8)` is `less(8)` - I took the decision to rename it from `jless(8)` to `jmore(8)` to avoid confusion. 14 | 15 | 16 | ### Why another `jail(8)` containers listing/managing tool? 17 | Because builtin `jls(8)` is very limited and does not display VNET IP(s) and interfaces. 18 | 19 | Also because - if You do now want to use full blown `jail(8)` manager such as BastilleBSD - which is very good by the way - the base system tools are just too limited for comfort work. 20 | 21 | I also needed a tool that will allow me to fast start/stop/restart FreeBSD `jail(8)` containers with minimal typing - more time to focus on what matters. 22 | 23 | ### Does it support listing BastilleBSD Jails? 24 | 25 | Yes - it reads `/usr/local/etc/bastille/bastille.conf` config and also checks `BAST_DIR` for `jail(8)` containers. 26 | 27 | ### Is it tested? 28 | 29 | Yes - its a modified and improved version of `https://github.com/vermaden/scripts/blob/master/jails.sh` that I already used for quite some time. 30 | 31 | 32 | ## Description 33 | 34 | Usage `help` info from the `jmore(8)` command below. 35 | 36 | ``` 37 | % jmore help 38 | usage: 39 | jmore list jail(8) containers 40 | jmore -a list jail(8) containers with all IP(s) 41 | jmore -h show help 42 | jmore --help show help 43 | jmore help show help 44 | jmore version show version 45 | 46 | manage: 47 | jmore start 48 | jmore restart 49 | jmore stop 50 | jmore status 51 | jmore console 52 | jmore shell 53 | jmore jexec 54 | 55 | shorts: 56 | jmore u UP ------> alias for start 57 | jmore d DOWN ----> alias for stop 58 | jmore r RESTART -> alias for restart 59 | jmore c CONSOLE -> alias for console|shell|jexec 60 | jmore s STATUS --> alias for status 61 | ``` 62 | 63 | ... and some fancy ASCII logo. 64 | 65 | ``` 66 | % jmore help 67 | __ ____ __ 68 | ___ / // \\ \ 69 | /__/__ __ _ ____ __ __ ____ / // / / \ \ 70 | / // \ / \ / /_// _ \/ / \ \ / / 71 | / // / / // / // / / ___/\ \ / / // / 72 | __/ //__/__/__/ \____//__/ \____/ \_\\____//_/ 73 | /____/ 74 | 75 | jmore(8) 0.1 2024/11/22 76 | 77 | ``` 78 | 79 | Example output from `jmore(8)` listing usage. 80 | 81 | ``` 82 | % jmore 83 | JAIL JID TYPE VER DIR IFACE IP(s) 84 | ---- --- ---- --- --- ----- ----- 85 | classic 5 std 13.2-R /jail/classic em0 10.0.0.199/32 86 | fbsdjail - std 13.1-R /jail/fbsdjail wlan0 10.0.0.43 87 | ctld-two - vnet 13.2-R /jail/ctld-two ${if}b - 88 | ctld - vnet 13.2-R /jail/ctld ${if}b - 89 | iscsi - vnet 13.2-R /jail/iscsi ${if}b - 90 | minecraft - std - [GONE]/jail/minecraft em0 10.0.0.210 91 | minio - std 14.0-R /jail/minio em0 10.0.0.133 92 | nfsd 3 vnet 14.1-R /jail/nfsd epair99b 10.1.1.99/24 93 | other - std 14.1-R /jail/other em0 10.0.0.199 94 | sambajail - vnet 14.1-R /jail/sambajail ${if}b - 95 | unfs3 - vnet 14.1-R /jail/unfs3 ${if}b - 96 | 97 | ``` 98 | 99 | EOF 100 | -------------------------------------------------------------------------------- /jmore: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Copyright (c) 2023-2025 Slawomir Wojciech Wojtczak (vermaden) 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that following conditions are met: 8 | # 1. Redistributions of source code must retain the above copyright 9 | # notice, this list of conditions and the following disclaimer. 10 | # 2. Redistributions in binary form must reproduce the above copyright 11 | # notice, this list of conditions and the following disclaimer in the 12 | # documentation and/or other materials provided with the distribution. 13 | # 14 | # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS 'AS IS' AND ANY 15 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | # DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY 18 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 | # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | # ------------------------------ 26 | # LIST AND MGMT FreeBSD jail(8) 27 | # ------------------------------ 28 | # vermaden [AT] interia [DOT] pl 29 | # https://vermaden.wordpress.com 30 | 31 | # display usage information 32 | __usage() { 33 | local NAME=${0##*/} 34 | echo "usage:" 35 | echo " ${NAME} list jail(8) containers" 36 | echo " ${NAME} -a list jail(8) containers with all IP(s)" 37 | echo " ${NAME} -h show help" 38 | echo " ${NAME} --help show help" 39 | echo " ${NAME} help show help" 40 | echo " ${NAME} version show version" 41 | echo 42 | echo "manage:" 43 | echo " ${NAME} start" 44 | echo " ${NAME} restart" 45 | echo " ${NAME} stop" 46 | echo " ${NAME} status" 47 | echo " ${NAME} console" 48 | echo " ${NAME} shell" 49 | echo " ${NAME} jexec" 50 | echo 51 | echo "shorts:" 52 | echo " ${NAME} u UP ------> alias for start" 53 | echo " ${NAME} d DOWN ----> alias for stop" 54 | echo " ${NAME} r RESTART -> alias for restart" 55 | echo " ${NAME} c CONSOLE -> alias for console|shell|jexec" 56 | echo " ${NAME} s STATUS --> alias for status" 57 | echo 58 | 59 | exit 1 60 | } 61 | 62 | # DISPLAY ONLY 3 FIRST INTERFACES 63 | __interfaces_limit() { 64 | if [ $( echo "${IFACE}" | wc -l | tr -d ' ' ) -gt 3 ] 65 | then 66 | IFACE=$( echo "${IFACE}" | head -3 | tr '\n' ' ' | tr ' ' '/' ) 67 | IFACE="${IFACE}(...)" 68 | else 69 | IFACE=$( echo "${IFACE}" | tr '\n' '/' | sed '$s/.$//' ) 70 | fi 71 | } 72 | 73 | # CHECK doas(1) AND/OR sudo(8) EXISTENCE 74 | unalias doas 75 | unalias sudo 76 | if which doas 1> /dev/null 2> /dev/null 77 | then 78 | DOAS=doas 79 | elif which sudo 1> /dev/null 2> /dev/null 80 | then 81 | DOAS=sudo 82 | else 83 | DOAS='' 84 | fi 85 | 86 | # CHECK PASSED ARGUMENTS 87 | case ${#} in 88 | (0) 89 | # DO NOTHING AND JUST DISPLAY LIST OF JAILS 90 | : 91 | ;; 92 | 93 | (1) 94 | # DISPLAY VERSION 95 | if [ "${1}" = "--version" -o \ 96 | "${1}" = "-version" -o \ 97 | "${1}" = "version" ] 98 | then 99 | echo " __ ____ __" 100 | echo " ___ / // \\\\ \\" 101 | echo " /__/__ __ _ ____ __ __ ____ / // / / \\ \\" 102 | echo " / // \\ / \\ / /_// _ \\/ / \ \\ / /" 103 | echo " / // / / // / // / / ___/\\ \\ / / // /" 104 | echo " __/ //__/__/__/ \\____//__/ \\____/ \\_\\\\____//_/" 105 | echo " /____/" 106 | echo 107 | echo "jmore(8) 0.2 2025/02/15" 108 | echo 109 | exit 0 110 | fi 111 | 112 | # DISPLAY HELP IF NEEDED 113 | case ${1} in 114 | (-h|--h|help|-help|--help) __usage ;; 115 | esac 116 | 117 | # DO FULL LISTING WITH ALL INTERFACES AND IP ADDRESSES 118 | [ "${1}" = "-a" ] && FULL_LISTING=1 119 | ;; 120 | 121 | (2) 122 | case ${2} in 123 | (u|start) ${DOAS} service jail onestart ${1} ;; 124 | (d|stop) ${DOAS} service jail onestop ${1} ;; 125 | (s|status) ${DOAS} service jail onestatus ${1} ;; 126 | (c|console|shell|jexec) 127 | env PS1="${1} # " PS2="> " ${DOAS} jexec ${1} 128 | ;; 129 | esac 130 | exit 0 131 | ;; 132 | 133 | (*) 134 | __usage 135 | ;; 136 | esac 137 | 138 | JLS=$( jls 2> /dev/null ) 139 | IFCONFIG=$( env IFCONFIG_FORMAT=inet:cidr ifconfig -l ether 2> /dev/null ) 140 | 141 | eval $( grep '^[^#]' /usr/local/etc/bastille/bastille.conf 2> /dev/null \ 142 | | grep -m 1 bastille_prefix \ 143 | | awk '{print $1}' ) 144 | 145 | if [ "${bastille_prefix}" != "" ] 146 | then 147 | BAST_DIR="${bastille_prefix}" 148 | unset bastille_prefix 149 | fi 150 | 151 | ( 152 | echo "JAIL JID TYPE VER DIR IFACE IP(s)" 153 | echo "---- --- ---- --- --- ----- -----" 154 | grep -h '^[^#]' \ 155 | /etc/jail.conf \ 156 | /etc/jail.conf.d/* \ 157 | "${BAST_DIR}"/jails/*/jail.conf 2> /dev/null \ 158 | | grep -h -E '[[:space:]]*[[:alnum:]][[:space:]]*\{' \ 159 | | tr -d '\ \t{' \ 160 | | while read JAIL 161 | do 162 | 163 | CONFIG=$( grep -h '^[^#]' /etc/jail.conf \ 164 | /etc/jail.conf.d/* \ 165 | "${BAST_DIR}"/jails/*/jail.conf 2> /dev/null \ 166 | | grep -A 512 -E "[[:space:]]*${JAIL}*[[:space:]]*\{" \ 167 | | grep -B 512 -m 1 ".*[[:space:]]*\}[[:space:]]*$" ) 168 | 169 | DIR=$( echo "${JLS}" | awk '{print $NF}' | grep -E -e "/${JAIL}$" -e "/${JAIL}/root" ) 170 | 171 | if [ "${DIR}" = "" ] 172 | then 173 | DIR=$( grep -h '^[^#]' \ 174 | /etc/jail.conf \ 175 | /etc/jail.conf.d/* \ 176 | "${BAST_DIR}"/jails/*/jail.conf 2> /dev/null \ 177 | | grep -A 512 -h -E '[[:alnum:]][[:space:]]\{' \ 178 | | grep -m 1 path \ 179 | | awk '{print $NF}' \ 180 | | tr -d ';' \ 181 | | sed -e "s.\${name}.${JAIL}.g" \ 182 | -e "s.\$name.${JAIL}.g" \ 183 | | tr -d '"' ) 184 | fi 185 | 186 | VER=$( ${DIR}/bin/freebsd-version -u 2> /dev/null \ 187 | | sed -e s.RELEASE.R.g \ 188 | -e s.CURRENT.C.g \ 189 | -e s.STABLE.S.g \ 190 | -e s.BETA.B.g ) 191 | 192 | if [ ! -d "${DIR}" ] 193 | then 194 | DIR="[GONE]${DIR}" 195 | fi 196 | 197 | IPS=$( jexec ${JAIL} env IFCONFIG_FORMAT=inet:cidr ifconfig 2> /dev/null \ 198 | | grep 'inet ' \ 199 | | grep -v 127.0.0.1 \ 200 | | awk '{print $2}' \ 201 | | tr '\n' '+' \ 202 | | sed '$s/.$//' ) 203 | 204 | TYPE=$( jexec ${JAIL} sysctl -n security.jail.vnet 2> /dev/null ) 205 | 206 | case ${TYPE} in 207 | 208 | (1) 209 | TYPE=vnet 210 | IFACE=$( jexec ${JAIL} env IFCONFIG_FORMAT=inet:cidr ifconfig -l ether 2> /dev/null | tr ' ' '\n' ) 211 | 212 | case ${FULL_LISTING} in 213 | 214 | (1) 215 | IFACE=$( echo "${IFACE}" | tr '\n' '/' | sed '$s/.$//' ) 216 | ;; 217 | 218 | (*) 219 | IPS=$( echo "${IPS}" | tr '+' '\n' | head -3 | tr '\n' '+' | sed '$s/.$//' ) 220 | __interfaces_limit 221 | ;; 222 | 223 | esac 224 | ;; 225 | 226 | (0) 227 | TYPE=std 228 | while read IP 229 | do 230 | while read INTERFACE 231 | do 232 | 233 | if env IFCONFIG_FORMAT=inet:cidr ifconfig ${INTERFACE} 2> /dev/null | grep -q "inet ${IP}" 234 | then 235 | IFACE=${INTERFACE} 236 | break 237 | fi 238 | done << EOF_INTERFACE 239 | $( echo "${IFCONFIG}" | tr ' ' '\n' ) 240 | EOF_INTERFACE 241 | done << EOF_IP 242 | $( echo "${IPS}" | tr '+' '\n' ) 243 | EOF_IP 244 | ;; 245 | 246 | (*) 247 | if echo "${CONFIG}" | grep -q 'vnet.interface' 248 | then 249 | TYPE=vnet 250 | IFACE=$( echo "${CONFIG}" | grep 'vnet.interface' | awk '{print $NF}' | tr -d ';"' | tr ',' '\n' ) 251 | __interfaces_limit 252 | else 253 | TYPE=std 254 | IFACE=$( echo "${CONFIG}" | grep 'interface' | awk '{print $NF}' | tr -d ';' | tr ',' '\n' ) 255 | __interfaces_limit 256 | IPS=$( echo "${CONFIG}" | grep '\.addr' | awk '{print $NF}' | tr -d ';' ) 257 | fi 258 | ;; 259 | 260 | esac 261 | 262 | JID=$( echo "${JLS}" | grep -E -e "/${JAIL}$" -e "/${JAIL}/root" | awk '{print $1}' ) 263 | 264 | if ! jexec ${JAIL} echo / 1> /dev/null 2> /dev/null 265 | then 266 | JID=- 267 | fi 268 | 269 | [ "${JID}" = "" ] && JID='-' 270 | [ "${TYPE}" = "" ] && TYPE='-' 271 | [ "${DIR}" = "" ] && DIR='-' 272 | [ "${IFACE}" = "" ] && IFACE='-' 273 | [ "${IPS}" = "" ] && IPS='-' 274 | [ "${VER}" = "" ] && VER='-' 275 | 276 | echo ${JAIL} ${JID} ${TYPE} ${VER} ${DIR} ${IFACE} ${IPS} 277 | 278 | unset JAIL JID TYPE VER DIR IFACE IPS 279 | 280 | done 281 | ) | column -t 282 | -------------------------------------------------------------------------------- /jmore.6: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # Copyright (c) 2023-2025 Slawomir Wojciech Wojtczak (vermaden) 4 | # Copyright (c) 2025 Christian Hofstede-Kuhn (chofstede) 5 | # All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that following conditions are met: 9 | # 1. Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # 2. Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # 15 | # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS 'AS IS' AND ANY 16 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | # DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY 19 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 | # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | 26 | # ------------------------------ 27 | # LIST AND MGMT FreeBSD jail(8) 28 | # ------------------------------ 29 | # vermaden [AT] interia [DOT] pl 30 | # https://vermaden.wordpress.com 31 | 32 | # display usage information 33 | __usage() { 34 | local NAME=${0##*/} 35 | echo "usage:" 36 | echo " ${NAME} list jail(8) containers" 37 | echo " ${NAME} -a list jail(8) containers with all IP(s)" 38 | echo " ${NAME} -h show help" 39 | echo " ${NAME} --help show help" 40 | echo " ${NAME} help show help" 41 | echo " ${NAME} version show version" 42 | echo 43 | echo "manage:" 44 | echo " ${NAME} start" 45 | echo " ${NAME} restart" 46 | echo " ${NAME} stop" 47 | echo " ${NAME} status" 48 | echo " ${NAME} console" 49 | echo " ${NAME} shell" 50 | echo " ${NAME} jexec" 51 | echo 52 | echo "shorts:" 53 | echo " ${NAME} u UP ------> alias for start" 54 | echo " ${NAME} d DOWN ----> alias for stop" 55 | echo " ${NAME} r RESTART -> alias for restart" 56 | echo " ${NAME} c CONSOLE -> alias for console|shell|jexec" 57 | echo " ${NAME} s STATUS --> alias for status" 58 | echo 59 | 60 | exit 1 61 | } 62 | 63 | # DISPLAY ONLY 3 FIRST INTERFACES 64 | __interfaces_limit() { 65 | if [ $( echo "${IFACE}" | wc -l | tr -d ' ' ) -gt 3 ] 66 | then 67 | IFACE=$( echo "${IFACE}" | head -3 | tr '\n' ' ' | tr ' ' '/' ) 68 | IFACE="${IFACE}(...)" 69 | else 70 | IFACE=$( echo "${IFACE}" | tr '\n' '/' | sed '$s/.$//' ) 71 | fi 72 | } 73 | 74 | # CHECK doas(1) AND/OR sudo(8) EXISTENCE 75 | unalias doas 76 | unalias sudo 77 | if which doas 1> /dev/null 2> /dev/null 78 | then 79 | DOAS=doas 80 | elif which sudo 1> /dev/null 2> /dev/null 81 | then 82 | DOAS=sudo 83 | else 84 | DOAS='' 85 | fi 86 | 87 | # CHECK PASSED ARGUMENTS 88 | case ${#} in 89 | (0) 90 | # DO NOTHING AND JUST DISPLAY LIST OF JAILS 91 | : 92 | ;; 93 | 94 | (1) 95 | # DISPLAY VERSION 96 | if [ "${1}" = "--version" -o \ 97 | "${1}" = "-version" -o \ 98 | "${1}" = "version" ] 99 | then 100 | echo " __ ____ __" 101 | echo " ___ / // \\\\ \\" 102 | echo " /__/__ __ _ ____ __ __ ____ / // / / \\ \\" 103 | echo " / // \\ / \\ / /_// _ \\/ / \ \\ / /" 104 | echo " / // / / // / // / / ___/\\ \\ / / // /" 105 | echo " __/ //__/__/__/ \\____//__/ \\____/ \\_\\\\____//_/" 106 | echo " /____/" 107 | echo 108 | echo "jmore(8) 0.2 2025/02/15" 109 | echo 110 | exit 0 111 | fi 112 | 113 | # DISPLAY HELP IF NEEDED 114 | case ${1} in 115 | (-h|--h|help|-help|--help) __usage ;; 116 | esac 117 | 118 | # DO FULL LISTING WITH ALL INTERFACES AND IP ADDRESSES 119 | [ "${1}" = "-a" ] && FULL_LISTING=1 120 | ;; 121 | 122 | (2) 123 | case ${2} in 124 | (u|start) ${DOAS} service jail onestart ${1} ;; 125 | (d|stop) ${DOAS} service jail onestop ${1} ;; 126 | (s|status) ${DOAS} service jail onestatus ${1} ;; 127 | (c|console|shell|jexec) 128 | env PS1="${1} # " PS2="> " ${DOAS} jexec ${1} 129 | ;; 130 | esac 131 | exit 0 132 | ;; 133 | 134 | (*) 135 | __usage 136 | ;; 137 | esac 138 | 139 | JLS=$( jls 2> /dev/null ) 140 | IFCONFIG=$( env IFCONFIG_FORMAT=inet:cidr ifconfig -l ether 2> /dev/null ) 141 | 142 | eval $( grep '^[^#]' /usr/local/etc/bastille/bastille.conf 2> /dev/null \ 143 | | grep -m 1 bastille_prefix \ 144 | | awk '{print $1}' ) 145 | 146 | if [ "${bastille_prefix}" != "" ] 147 | then 148 | BAST_DIR="${bastille_prefix}" 149 | unset bastille_prefix 150 | fi 151 | 152 | ( 153 | printf "%-28s %-4s %-5s %-7s %-15s %-15s %s\n" "JAIL" "JID" "TYPE" "VER" "DIR" "IFACE" "IP(s)" 154 | printf "%-28s %-4s %-5s %-7s %-15s %-15s %s\n" "----" "---" "----" "---" "---" "-----" "-----" 155 | 156 | grep -h '^[^#]' \ 157 | /etc/jail.conf \ 158 | /etc/jail.conf.d/* \ 159 | "${BAST_DIR}"/jails/*/jail.conf 2> /dev/null \ 160 | | grep -h -E '[[:space:]]*[[:alnum:]][[:space:]]*\{' \ 161 | | tr -d '\ \t{' \ 162 | | while read JAIL 163 | do 164 | 165 | CONFIG=$( grep -h '^[^#]' /etc/jail.conf \ 166 | /etc/jail.conf.d/* \ 167 | "${BAST_DIR}"/jails/*/jail.conf 2> /dev/null \ 168 | | grep -A 512 -E "[[:space:]]*${JAIL}*[[:space:]]*\{" \ 169 | | grep -B 512 -m 1 ".*[[:space:]]*\}[[:space:]]*$" ) 170 | 171 | DIR=$( echo "${JLS}" | awk '{print $NF}' | grep -E -e "/${JAIL}$" -e "/${JAIL}/root" ) 172 | 173 | if [ "${DIR}" = "" ] 174 | then 175 | DIR=$( grep -h '^[^#]' \ 176 | /etc/jail.conf \ 177 | /etc/jail.conf.d/* \ 178 | "${BAST_DIR}"/jails/*/jail.conf 2> /dev/null \ 179 | | grep -A 512 -h -E '[[:alnum:]][[:space:]]\{' \ 180 | | grep -m 1 path \ 181 | | awk '{print $NF}' \ 182 | | tr -d ';' \ 183 | | sed -e "s.\${name}.${JAIL}.g" \ 184 | -e "s.\$name.${JAIL}.g" \ 185 | | tr -d '"' ) 186 | fi 187 | 188 | VER=$( ${DIR}/bin/freebsd-version -u 2> /dev/null \ 189 | | sed -e s.RELEASE.R.g \ 190 | -e s.CURRENT.C.g \ 191 | -e s.STABLE.S.g \ 192 | -e s.BETA.B.g ) 193 | 194 | if [ ! -d "${DIR}" ] 195 | then 196 | DIR="[GONE]${DIR}" 197 | fi 198 | 199 | IPS=$( jexec "${JAIL}" ifconfig 2>/dev/null \ 200 | | awk ' 201 | $1 == "inet" && $2 != "127.0.0.1" { print $2 } 202 | $1 == "inet6" && $2 !~ /^fe80/ && $2 != "::1" { print $2 } 203 | ' | tr '\n' '+' | sed 's/+$//' ) 204 | 205 | TYPE=$( jexec ${JAIL} sysctl -n security.jail.vnet 2> /dev/null ) 206 | 207 | case ${TYPE} in 208 | 209 | (1) 210 | TYPE=vnet 211 | IFACE=$( jexec ${JAIL} env IFCONFIG_FORMAT=inet:cidr ifconfig -l ether 2> /dev/null | tr ' ' '\n' ) 212 | 213 | case ${FULL_LISTING} in 214 | 215 | (1) 216 | IFACE=$( echo "${IFACE}" | tr '\n' '/' | sed '$s/.$//' ) 217 | ;; 218 | 219 | (*) 220 | IPS=$( echo "${IPS}" | tr '+' '\n' | head -3 | tr '\n' '+' | sed '$s/.$//' ) 221 | __interfaces_limit 222 | ;; 223 | 224 | esac 225 | ;; 226 | 227 | (0) 228 | TYPE=std 229 | while read IP 230 | do 231 | while read INTERFACE 232 | do 233 | 234 | if env IFCONFIG_FORMAT=inet:cidr ifconfig ${INTERFACE} 2> /dev/null | grep -q "inet ${IP}" 235 | then 236 | IFACE=${INTERFACE} 237 | break 238 | fi 239 | done << EOF_INTERFACE 240 | $( echo "${IFCONFIG}" | tr ' ' '\n' ) 241 | EOF_INTERFACE 242 | done << EOF_IP 243 | $( echo "${IPS}" | tr '+' '\n' ) 244 | EOF_IP 245 | ;; 246 | 247 | (*) 248 | if echo "${CONFIG}" | grep -q 'vnet.interface' 249 | then 250 | TYPE=vnet 251 | IFACE=$( echo "${CONFIG}" | grep 'vnet.interface' | awk '{print $NF}' | tr -d ';"' | tr ',' '\n' ) 252 | __interfaces_limit 253 | else 254 | TYPE=std 255 | IFACE=$( echo "${CONFIG}" | grep 'interface' | awk '{print $NF}' | tr -d ';' | tr ',' '\n' ) 256 | __interfaces_limit 257 | IPS=$( echo "${CONFIG}" | grep '\.addr' | awk '{print $NF}' | tr -d ';' ) 258 | fi 259 | ;; 260 | 261 | esac 262 | 263 | JID=$( echo "${JLS}" | grep -E -e "/${JAIL}$" -e "/${JAIL}/root" | awk '{print $1}' ) 264 | 265 | if ! jexec ${JAIL} echo / 1> /dev/null 2> /dev/null 266 | then 267 | JID=- 268 | fi 269 | 270 | [ "${JID}" = "" ] && JID='-' 271 | [ "${TYPE}" = "" ] && TYPE='-' 272 | [ "${DIR}" = "" ] && DIR='-' 273 | [ "${IFACE}" = "" ] && IFACE='-' 274 | [ "${IPS}" = "" ] && IPS='-' 275 | [ "${VER}" = "" ] && VER='-' 276 | 277 | FIRST_IP=$( echo "${IPS}" | tr '+' '\n' | head -1 ) 278 | REST_IPS=$( echo "${IPS}" | tr '+' '\n' | tail -n +2 ) 279 | 280 | printf "%-28s %-4s %-5s %-7s %-15s %-15s %s\n" "${JAIL}" "${JID}" "${TYPE}" "${VER}" "${DIR}" "${IFACE}" "${FIRST_IP}" 281 | 282 | for ip in ${REST_IPS}; do 283 | printf "%80s%s\n" "" "$ip" # 80 = width of 6 previous fields 284 | done 285 | 286 | unset JAIL JID TYPE VER DIR IFACE IPS 287 | 288 | done 289 | ) 290 | 291 | --------------------------------------------------------------------------------