←︎ random :: 4a370e9


1
commit 4a370e92de957859f870142d561794cb1facff00 (HEAD -> master)
2
Author: acidvegas <acid.vegas@acid.vegas>
3
Date:   Thu Aug 1 22:15:39 2019 -0400
4
5
    update
6
---
7
 2fa.py                 |   4 +-
8
 acidbox/setup          |  10 ++--
9
 btkb.sh                |  12 ----
10
 docs/gpg.md            |  28 ++++-----
11
 docs/ssh.md            |  43 +++++++-------
12
 gitremote.sh           |  14 -----
13
 mkchroot               | 153 +++++++++++++++++++++++++++++++++++++++++++++++++
14
 networking/ap.py       |  23 --------
15
 networking/discover.py |   4 +-
16
 progress.sh            |   7 +++
17
 scales.py              |  88 ----------------------------
18
 11 files changed, 207 insertions(+), 179 deletions(-)
19
20
diff --git a/2fa.py b/2fa.py
21
index c11897f..50c2add 100644
22
--- a/2fa.py
23
+++ b/2fa.py
24
@@ -35,11 +35,11 @@ secret = input('secret : ') or pyotp.random_base32()
25
 uri = pyotp.totp.TOTP(secret).provisioning_uri(name, issuer)
26
 qr = qrgen(uri).replace(' ', ' ')[:-1]
27
 max_len = len(qr.split('\n')[1])
28
-print(uri+'\n'+qr)
29
+print(f'{uri}\n{qr}')
30
 del name, issuer, uri, qr
31
 while True:
32
 	code = pyotp.TOTP(secret).now()
33
 	seconds = int(time.strftime('%S'))
34
 	remain = 60-seconds if seconds >= 30 else 30-seconds
35
-	print(f'{code} ({remain})'.center(max_len),  end='\r')
36
+	print(f'{code} ({remain})'.center(max_len), end='\r')
37
 	time.sleep(1)
38
diff --git a/acidbox/setup b/acidbox/setup
39
index aa27fa6..462d262 100755
40
--- a/acidbox/setup
41
+++ b/acidbox/setup
42
@@ -1,7 +1,7 @@
43
 #!/bin/sh
44
 set -e
45
 
46
-function setup_motd() {
47
+setup_motd() {
48
 	RESET='\033[0m'
49
 	GREEN='\033[0;32m'
50
 	BGREEN='\033[1;32m'
51
@@ -11,7 +11,7 @@ function setup_motd() {
52
 	RED='\033[1;31m'
53
 	BLUE='\033[1;34m'
54
 	UBLUE='\033[4;34m'
55
-	echo "╔═══════════════════════╦══════════════════════════════════════════════════════════════╗
56
+	echo -e "╔═══════════════════════╦══════════════════════════════════════════════════════════════╗
57
 ║${GREEN}  ▄▄▄·  ▄▄· ▪  ·▄▄▄▄   ${RESET}║                    ${RED}Connection Notice${RESET}                         ║
58
 ║${GREEN} ▐█ ▀█ ▐█ ▌▪██ ██▪ ██  ${RESET}╟──────────────────────────────────────────────────────────────╢
59
 ║${GREEN} ▄█▀▀█ ██ ▄▄▐█·▐█· ▐█▌ ${RESET}║                                                              ║
60
@@ -33,7 +33,7 @@ ${YELLOW}Type ${BGREEN}cmds${YELLOW} to see a list of commands available.${RESET
61
  ${GREY}*${YELLOW} Stay in your home directory, keep the system clean, and make regular backups." > /etc/motd
62
 }
63
 
64
-function setup_user() {
65
+setup_user() {
66
 	sudo useradd -m -G ssh -s /bin/bash $1
67
 	mkdir /home/$1/.scripts
68
 	wget -O /home/$1/.bashrc             https://git.supernets.org/acidvegas/acidbox/blob/master/files/.bashrc
69
@@ -43,4 +43,6 @@ function setup_user() {
70
 	wget -O /home/$1/.scripts/vhosts     https://git.supernets.org/acidvegas/acidbox/blob/master/files/vhosts
71
 	echo "clear && reset" > /home/$1/.bash_logout
72
 	echo "[[ -f ~/.bashrc ]] && . ~/.bashrc" > /home/$1/.bash_profile
73
-}
74
+}
75
+
76
+setup_motd
77
diff --git a/btkb.sh b/btkb.sh
78
deleted file mode 100644
79
index 6b56fa3..0000000
80
--- a/btkb.sh
81
+++ /dev/null
82
@@ -1,12 +0,0 @@
83
-#!/bin/sh
84
-sudo pacman -S bluez bluez-utils
85
-sudo systemctl enable bluetooth && sudo systemctl start bluetooth
86
-sudo sed -i 's/#AutoEnable=false/AutoEnable=true/' /etc/bluetooth/main.conf
87
-bluetoothctl power on
88
-bluetoothctl agent KeyboardOnly
89
-bluetoothctl pairable on
90
-bluetoothctl scan on
91
-bluetoothctl pair CC:C5:0A:20:91:5B
92
-bluetoothctl trust CC:C5:0A:20:91:5B
93
-bluetoothctl connect CC:C5:0A:20:91:5B
94
-bluetoothctl scan off
95
diff --git a/docs/gpg.md b/docs/gpg.md
96
index af24aba..6689b38 100644
97
--- a/docs/gpg.md
98
+++ b/docs/gpg.md
99
@@ -1,4 +1,6 @@
100
-# Create a key
101
+# GPG Cheat Sheet
102
+
103
+## Create a key
104
 `gpg --expert --full-generate-key`
105
 * RSA (set your own capabilities)
106
 * Set to Certify only.
107
@@ -10,7 +12,7 @@
108
 * `adduid`
109
 * `save`
110
 
111
-# Backup key
112
+## Backup key
113
 * `mv ~/.gnupg/secring.gpg ~/.backup/gpg/`
114
 * `mv ~/.gnupg/pubring.gpg ~/.backup/gpg/`
115
 * `gpg -a --export-secret-key <userid> > secret_key.gpg`
116
@@ -20,25 +22,25 @@
117
 * `gpg --list-secret-keys`
118
 * `rm secret_subkeys.gpg`
119
 
120
-# Revoke cert
121
+## Revoke cert
122
 * `gpg -a --output revoke.asc --gen-revoke '<fingerprint>'`
123
 
124
-# Import/Export public key
125
+## Import/Export public key
126
 * `gpg --import public.key`
127
 * `gpg --output public.key --armor --export <userid>`
128
 
129
-# Import/Export private key
130
+## Import/Export private key
131
 * `gpg --export-secret-keys --armor <userid> > privkey.asc`
132
 * `gpg --import privkey.asc`
133
 
134
-# Edit keys
135
+## Edit keys
136
 * `gpg --edit-key <userid>`
137
 
138
-# List (secret) keys
139
+## List (secret) keys
140
 * `gpg --list-keys`
141
 * `gpg --list-secret-keys`
142
 
143
-# Encrypt/Decrypt
144
+## Encrypt/Decrypt
145
 * `gpg --recipient user-id --encrypt doc`
146
 * `gpg --output doc --decrypt doc.gpg`
147
 
148
@@ -47,26 +49,26 @@ or...
149
 * `gpg -c --s2k-cipher-algo AES256 --s2k-digest-algo SHA512 --s2k-count 65536 doc`
150
 * `gpg --output doc --decrypt doc.gpg`
151
 
152
-# Signing
153
+## Signing
154
 * `gpg --output doc.sig --sign doc`
155
 * `gpg --output doc.sig --clearsign doc`
156
 * `gpg --output doc.sig --detach-sig doc`
157
 
158
-# Verify
159
+## Verify
160
 * `gpg --verify doc.sig`
161
 * `gpg --verify archlinux-version.iso.sig`
162
 * `gpg --verify archlinux-version.iso.sig /path/to/archlinux-version.iso`
163
 * `gpg --with-fingerprint <keyfile>`
164
 
165
-# Send keys
166
+## Send keys
167
 * `gpg --send-keys <userid>`
168
 * `gpg --refresh-keys`
169
 
170
-# Get keys
171
+## Get keys
172
 * `gpg --recv-key '<fingerprint>'`
173
 * `gpg --fingerprint '<fingerprint>'`
174
 
175
-# Sign key
176
+## Sign key
177
 * `gpg --lsign-key '<fingerprint>'`
178
 
179
 or...
180
diff --git a/docs/ssh.md b/docs/ssh.md
181
index d3fd080..4bc551f 100644
182
--- a/docs/ssh.md
183
+++ b/docs/ssh.md
184
@@ -1,8 +1,9 @@
185
-A full write-up on OpenSSH usage with security in mind.
186
+# SSH Security
187
+> A full write-up on OpenSSH usage with security in mind.
188
 
189
 ---
190
 
191
-# Table of Contents
192
+## Table of Contents
193
 * [Generating An SSH Key Pair](#generating-an-ssh-key-pair)
194
 	- [Linux](#linux)
195
 	- [Windows](#windows)
196
@@ -29,8 +30,8 @@ A full write-up on OpenSSH usage with security in mind.
197
 
198
 ---
199
 
200
-## Generating An SSH Key Pair
201
-### Linux
202
+### Generating An SSH Key Pair
203
+#### Linux
204
 Generate a key using the **Ed25519** algorithm with 500 KDF rounds:
205
 * `ssh-keygen -t ed25519 -a 500 -C "$(whoami)@$(hostname)-$(date -I)"`
206
 
207
@@ -42,7 +43,7 @@ You only need to backup your private key. Public keys can be regenerated from th
208
 Copy your public key to clipboard:
209
 * `cat ~/.ssh/acidvegas@pi-2017-01-01.pub`
210
 
211
-### Windows
212
+#### Windows
213
 Download & run [puttygen](https://the.earth.li/~sgtatham/putty/latest/w32/puttygen.exe).
214
 
215
 Once opened, change the key type to **ED25519** under the *Parameters* box, and then click the *Generate* button.
216
@@ -53,8 +54,8 @@ You only need to backup your private key. Public keys can be regenerated by clic
217
 
218
 Copy the data in the box labeled *Public key for pasting into OpenSSH authorized_keys file*.
219
 
220
-## Getting Your Client To Use Your SSH Key
221
-### Linux
222
+### Getting Your Client To Use Your SSH Key
223
+#### Linux
224
 * `ssh -p 65150 -i ~/.ssh/acidvegas@pi-2017-01-01 acidvegas@192.168.1.10`
225
 
226
 or...
227
@@ -71,7 +72,7 @@ Host acidbox
228
 * `chmod 600 ~/.ssh/config`
229
 * Usage: `ssh acidbox`
230
 
231
-### Windows
232
+#### Windows
233
 Download & run the [putty](https://the.earth.li/~sgtatham/putty/latest/w32/putty.exe) client.
234
 
235
 Once opened, select `Connection -> SSH -> Auth` from the *Category* box. Click the *Browse* button and select your private key.
236
@@ -84,8 +85,8 @@ SSH into your server by clicking your saved session from the *Saved Sessions* bo
237
 
238
 ---
239
 
240
-## Setup Server
241
-### Harden OpenSSH Daemon
242
+### Setup Server
243
+#### Harden OpenSSH Daemon
244
 * `nano /etc/ssh/sshd_config`
245
 ```
246
 AddressFamily any
247
@@ -128,7 +129,7 @@ Protocol 2
248
 * The `Port` option should be set to a non-standard port *(High-value port number recommended)*. 
249
 * The `PrintMotd` option can be changed to **yes** if the file `/etc/motd` exists. This is shown after the user authenticates.
250
 
251
-### Create A New User On The Server
252
+#### Create A New User On The Server
253
 Create a new user on the server with a password:
254
 * `useradd -m -s /bin/bash acidvegas`
255
 * `passwd acidvegas`
256
@@ -137,7 +138,7 @@ Create an **ssh** group and add your user to the group.
257
 * `groupadd ssh`
258
 * `gpasswd -a acidvegas ssh`
259
 
260
-### Copy Your Public Key To Your Shell
261
+#### Copy Your Public Key To Your Shell
262
 * `nano /etc/ssh/authorized_keys/acidvegas` *(Paste your public key data in this file)*
263
 
264
 **Note:** This is only required if you are using the `AuthorizedKeysFile /etc/ssh/authorized_keys/%u` line in your `sshd_config` file. For using the standard `~/.ssh/authorized_keys` file, do the follow:
265
@@ -152,8 +153,8 @@ Create an **ssh** group and add your user to the group.
266
 
267
 ---
268
 
269
-# Extra Security
270
-### Allow Incoming SSH Connections Through IPTables
271
+### Extra Security
272
+#### Allow Incoming SSH Connections Through IPTables
273
 ```
274
 iptables -A INPUT  -i eth0 -p tcp --dport 65150 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
275
 iptables -A OUTPUT -o eth0 -p tcp --sport 65150 -m conntrack --ctstate ESTABLISHED     -j ACCEPT
276
@@ -164,10 +165,10 @@ You can also allow only incomming connection from a specific IP address instead
277
 iptables -A INPUT -i eth0 -p tcp -s 192.168.1.99 --dport 65150 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
278
 ```
279
 
280
-### Lock Users In A Chroot Jail Environment
281
+#### Lock Users In A Chroot Jail Environment
282
 See [mkchroot](https://github.com/acidvegas/mkchroot) repository for details.
283
 
284
-### Port Knocking
285
+#### Port Knocking
286
 The following is an example which uses the port knocking sequence `8881 -> 7777 -> 9991` to open port 65150 for 30 seconds.
287
 
288
 ##### Server 
289
@@ -216,8 +217,8 @@ Download & install the [knockd](http://www.zeroflux.org/projects/knock) package.
290
 	stop_command  = /usr/bin/iptables -D TCP -s %IP% -p tcp --dport 65150 -j ACCEPT
291
 ```
292
 
293
-##### Knocking Your Server
294
-###### Using Nmap
295
+#### Knocking Your Server
296
+##### Using Nmap
297
 Download & install the [nmap](https://nmap.org/) package.
298
 
299
 * `nano knock.sh`
300
@@ -232,12 +233,12 @@ done
301
 ```
302
 * Usage: `sh knock.sh example.server.com 8881 7777 9991`
303
 
304
-###### Using Knockd
305
+##### Using Knockd
306
 Download & install the [knockd](http://www.zeroflux.org/projects/knock) package.
307
 
308
 * `knock -v example.server.com 8881:tcp 7777:tcp 9991:tcp`
309
 
310
-### Jump Hosts
311
+#### Jump Hosts
312
 * `ssh -J <jumphost> <host>`
313
 
314
 The `<jumphost>` option can be `user@host`, `user@host:port` or an host setup in your `~/.ssh/config`.
315
@@ -265,7 +266,7 @@ Connect to your target host with `ssh targetbox`
316
 
317
 ---
318
 
319
-## Sources
320
+### Sources
321
 * https://wiki.archlinux.org/index.php/Port_knocking
322
 * https://wiki.archlinux.org/index.php/SSH_keys
323
 * https://wiki.mozilla.org/Security/Guidelines/OpenSSH
324
diff --git a/gitremote.sh b/gitremote.sh
325
deleted file mode 100644
326
index ce6bb3f..0000000
327
--- a/gitremote.sh
328
+++ /dev/null
329
@@ -1,14 +0,0 @@
330
-#!/bin/sh
331
-set -e
332
-for u in $HOME/dev/git/*/; do
333
-	for d in $(find $u -name .git -type d -prune | sort); do
334
-		u=$(basename $u)
335
-		r=$(basename -s .git `git --git-dir $d config --get remote.origin.url`)
336
-		echo "updating $r..."
337
-		git -C $d remote remove origin
338
-		git -C $d remote add origin git@github.com:$s/$r.git
339
-		git -C $d remote set-url --add --push origin git@github.com:$u/$r.git
340
-		git -C $d remote set-url --add --push origin git@gitlab.com:$u/$r.git
341
-		git -C $d remote set-url --add --push origin git@contra:$r.git
342
-	done
343
-done
344
diff --git a/mkchroot b/mkchroot
345
new file mode 100755
346
index 0000000..4b22e2c
347
--- /dev/null
348
+++ b/mkchroot
349
@@ -0,0 +1,153 @@
350
+#!/bin/sh
351
+set -e
352
+
353
+CHROOT_BASE="/var/jail"
354
+
355
+display_help() {
356
+	echo "usage: mkchroot [option]"
357
+	echo -e "\nexample: mkchroot --create=acidvegas bash cp irssi ls mkdir mv rm screen wget"
358
+	echo -e "\noptions:"
359
+	echo "  -c, --create=USER   <cmds>  create a new chroot jail"
360
+	echo "  -d, --destroy=USER          destroy a chroot jail"
361
+	echo "  -l, --list                  list chroot jails"
362
+	echo "  -h, --help                  display this help and exit"
363
+}
364
+
365
+create_jail() {
366
+	[ $EUID -ne 0 ] && echo "insufficent privledges" && exit 1
367
+	if [ ${#1} -ne 2 ]; then
368
+		CHROOT_USER="${1#*=}"
369
+		CHROOT_CMDS="${@:2}"
370
+	else
371
+		CHROOT_USER=$2
372
+		CHROOT_CMDS="${@:3}"
373
+	fi
374
+	CHROOT_DIR="$CHROOT_BASE/$CHROOT_USER"
375
+	CHROOT_PWD="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 25 | head -n 1)"
376
+	[ -d $CHROOT_DIR ] && echo "chroot jail already exists for $CHROOT_USER at $CHROOT_DIR" && exit 1
377
+	echo "creating initial directory structure..."
378
+	mkdir -v $CHROOT_DIR
379
+	mkdir -pv $CHROOT_DIR/{dev,etc,home,proc,usr}
380
+	mkdir -v $CHROOT_DIR/dev/pts
381
+	mkdir -v $CHROOT_DIR/home/$CHROOT_USER
382
+	mkdir -v $CHROOT_DIR/usr/share
383
+	echo "making required devices nodes..."
384
+	mknod -m 666 $CHROOT_DIR/dev/null c 1 3
385
+	echo "created device node: $CHROOT_DIR/dev/null"
386
+	mknod -m 666 $CHROOT_DIR/dev/tty c 5 0
387
+	echo "created device node: $CHROOT_DIR/dev/tty"
388
+	mknod -m 666 $CHROOT_DIR/dev/random c 1 8
389
+	echo "created device node: $CHROOT_DIR/dev/random"
390
+	mknod -m 666 $CHROOT_DIR/dev/zero c 1 5
391
+	echo "created device node: $CHROOT_DIR/dev/zero"
392
+	echo "copying required shared libraries..."
393
+	for x in ${CHROOT_CMDS[@]}; do
394
+		for y in $(ldd $(which $x)|grep -v dynamic|cut -d " " -f 3|sed 's/://'|sort|uniq); do
395
+			cp --parents -v $y $CHROOT_DIR
396
+		done
397
+	done
398
+	echo "copying additional required files..."
399
+	if [ ! -d $CHROOT_DIR/bin ] && [ -d $CHROOT_DIR/usr/bin ]; then
400
+		cp -r $CHROOT_DIR/usr/bin $CHROOT_DIR/bin	# This can be improved.
401
+	fi
402
+	if [ ! -d $CHROOT_DIR/lib ] && [ -d $CHROOT_DIR/usr/lib ]; then
403
+		cp -r $CHROOT_DIR/usr/lib $CHROOT_DIR/lib	# This can be improved.
404
+	fi
405
+	cp -v /etc/{hosts,ld.so.cache,ld.so.conf,localtime,nsswitch.conf,resolv.conf} $CHROOT_DIR/etc/
406
+	cp -v /lib/ld-linux.so.* $CHROOT_DIR/lib/
407
+	cp -rv /lib/terminfo/ $CHROOT_DIR/lib/
408
+	cp -rv /usr/share/terminfo/ $CHROOT_DIR/usr/share/
409
+	grep $CHROOT_USER /etc/passwd > $CHROOT_DIR/etc/passwd
410
+	grep $CHROOT_USER /etc/group  > $CHROOT_DIR/etc/group
411
+	grep $CHROOT_USER /etc/shadow > $CHROOT_DIR/etc/shadow
412
+	echo -e "[[ \$- != *i* ]] && return\nalias ls='ls --color=auto'\nPS1='\e[1;30mjail\e[0m | \e[1;34m> \e[0;32m\w \e[0;37m: '" > $CHROOT_DIR/home/$CHROOT_USER/.bash_profile
413
+	if ! id $CHROOT_USER >/dev/null 2>&1; then
414
+		useradd -s /bin/bash -M -p $CHROOT_PWD $CHROOT_USER
415
+		echo "added $CHROOT_USER user"
416
+	fi
417
+	if [ ! $(getent group jail) ]; then
418
+		groupadd jail
419
+		echo "added jail group"
420
+	fi
421
+	if ! getent group jail | grep &>/dev/null "\b${CHROOT_USER}\b"; then
422
+		gpasswd -a $CHROOT_USER jail
423
+		echo "added $CHROOT_USER to jail group"
424
+	fi
425
+	echo "setting permissions..."
426
+	chown -v root:root $CHROOT_DIR
427
+	chown -v root:tty $CHROOT_DIR/dev/tty
428
+	chown -v $CHROOT_USER:$CHROOT_USER $CHROOT_DIR/home/$CHROOT_USER
429
+	chmod -Rv 755 $CHROOT_DIR/home/$CHROOT_USER
430
+	chattr +i $CHROOT_DIR/etc/group
431
+	chattr +i $CHROOT_DIR/etc/hosts
432
+	chattr +i $CHROOT_DIR/etc/nsswitch.conf
433
+	chattr +i $CHROOT_DIR/etc/passwd
434
+	chattr +i $CHROOT_DIR/etc/resolv.conf
435
+	chattr +i $CHROOT_DIR/etc/shadow
436
+	echo "mounting pseudoterminal slave device on $CHROOT_DIR/dev/pts"
437
+	if ! grep -q "devpts $CHROOT_DIR/dev/pts devpts rw,noatime,mode=600,ptmxmode=000 0 0" /etc/fstab; then
438
+		echo -e "\ndevpts $CHROOT_DIR/dev/pts devpts rw,noatime,mode=600,ptmxmode=000 0 0" >> /etc/fstab
439
+		mount -av
440
+	fi
441
+	if ! grep -q "proc $CHROOT_DIR/proc proc rw,noatime,gid=26,hidepid=2 0 0" /etc/fstab; then
442
+		echo -e "\nproc $CHROOT_DIR/proc proc rw,noatime,gid=26,hidepid=2 0 0" >> /etc/fstab
443
+		mount -av
444
+	fi
445
+	if grep -q "AuthorizedKeysFile" /etc/ssh/sshd_config; then
446
+		if ! grep -q "AuthorizedKeysFile /etc/ssh/authorized_keys/%u" /etc/ssh/sshd_config; then
447
+			sed 's/AuthorizedKeysFile.*/AuthorizedKeysFile /etc/ssh/authorized_keys/%u/' /etc/ssh/sshd_config > /etc/ssh/sshd_config
448
+			echo "updated sshd_config with AuthorizedKeysFile"
449
+		fi
450
+	else
451
+		sed -i "1iAuthorizedKeysFile /etc/ssh/authorized_keys/%u" /etc/ssh/sshd_config
452
+	fi
453
+	if ! grep $'Match Group jail\n\tChrootDirectory /var/jail/%u' /etc/ssh/sshd_config; then
454
+		echo -e "\nMatch Group jail\n\tChrootDirectory /var/jail/%u" >> /etc/ssh/sshd_config
455
+		echo "updated sshd_config with ChrootDirectory"
456
+	fi
457
+	echo -e "\nchroot jail for $CHROOT_USER created at $CHROOT_DIR"
458
+	echo "password for $CHROOT_USER is: $CHROOT_PWD"
459
+}
460
+
461
+destroy_jail() {
462
+	[ $EUID -ne 0 ] && echo "insufficent privledges" && exit 1
463
+	if [[ ${#1} -ne 2 ]]; then
464
+		CHROOT_USER="${1#*=}"
465
+	else
466
+		CHROOT_USER=$2
467
+	fi
468
+	CHROOT_DIR="$CHROOT_BASE/$CHROOT_USER"
469
+	if mount | grep -q "$CHROOT_DIR/dev/pts"; then
470
+		umount -v $CHROOT_DIR/dev/pts
471
+		echo "unmounted pseudoterminal slave device"
472
+	fi
473
+	if mount | grep -q "$CHROOT_DIR/proc"; then
474
+		umount -v $CHROOT_DIR/proc
475
+		echo "unmounted proc device"
476
+	fi
477
+	if [ -d $CHROOT_DIR ]; then
478
+		chattr -i $CHROOT_DIR/etc/*
479
+		rm -rfv $CHROOT_DIR
480
+	fi
481
+	if id $CHROOT_USER >/dev/null 2>&1; then
482
+		userdel -f $CHROOT_USER
483
+		echo "deleted $CHROOT_USER user"
484
+	fi
485
+	echo "jail destroyed"
486
+}
487
+
488
+list_jails() {
489
+	CHROOT_DIRS=$(getent group jail | cut -d: -f4 | sed 's/,/ /g')
490
+	for i in ${CHROOT_DIRS[@]}; do
491
+		echo " * $i"
492
+	done
493
+}
494
+
495
+[ "$#" -eq 0 ] && echo -e "invalid or missing arguments\n" && display_help && exit 1
496
+case $1 in
497
+	-c|--create=*)  create_jail  "$@" ;;
498
+	-d|--destroy=*) destroy_jail "$@" ;;
499
+	-l|--list)      list_jails        ;;
500
+	-h|--help)      display_help      ;;
501
+	*) echo -e "invalid or missing arguments\n"; display_help ; exit 1;;
502
+esac
503
diff --git a/networking/ap.py b/networking/ap.py
504
deleted file mode 100644
505
index 48545fc..0000000
506
--- a/networking/ap.py
507
+++ /dev/null
508
@@ -1,23 +0,0 @@
509
-#!/usr/bin/env python
510
-import re, subprocess
511
-
512
-interface = 'wlp1s0'
513
-
514
-def between(source, start, stop):
515
-	data = re.compile(start + '(.*?)' + stop, re.IGNORECASE|re.MULTILINE).search(source)
516
-	if data : return data.group(1)
517
-	else    : return False
518
-
519
-output = subprocess.check_output(f'sudo iwlist {interface} scanning  | egrep \'Cell |Channel|Frequency|Encryption|Quality|ESSID|Mode\'', shell=True).decode()
520
-access_points = output.split(' Cell ')[1:]
521
-print('\033[30m\033[47mMAC Address         Channel   Frequency   Quality   Signal    Mode     Encryption   ESSID\033[0m')
522
-for ap in access_points:
523
-	address    = between(ap, 'Address: ',             '\n')
524
-	channel    = between(ap, 'Channel:',              '\n').ljust(7)
525
-	frequency  = between(ap, 'Frequency:',          ' GHz')[:3]
526
-	quality    = between(ap, 'Quality=',        '  Signal')
527
-	signal     = between(ap, 'Signal level=',       ' dBm')
528
-	encryption = between(ap, 'Encryption key:',       '\n').ljust(10)
529
-	essid      = between(ap, 'ESSID:\"',            '\"\n')
530
-	mode       = between(ap, 'Mode:',                 '\n')
531
-	print(f'{address} | {channel} | {frequency} GHz   | {quality}   | {signal} dBm | {mode} | {encryption} | {essid}')
532
diff --git a/networking/discover.py b/networking/discover.py
533
index 23d9538..d3a4343 100644
534
--- a/networking/discover.py
535
+++ b/networking/discover.py
536
@@ -4,7 +4,7 @@ import subprocess
537
 def portscan(ip):
538
 	ports = list()
539
 	try:
540
-		cmd = subprocess.check_output('sudo nmap -F ' + ip, shell=True).decode()
541
+		cmd = subprocess.check_output('nmap -F ' + ip, shell=True).decode()
542
 		output = cmd.split('SERVICE')[1].split('MAC')[0].split('\n')
543
 		for item in output:
544
 			port = item.split('/')[0]
545
@@ -17,7 +17,7 @@ def portscan(ip):
546
 def scanhosts(subnet):
547
 	data = list()
548
 	matrix = {'ip':list(),'host':list(),'ports':list()}
549
-	cmd = subprocess.check_output(f'sudo nmap -sP {subnet}/24', shell=True).decode()
550
+	cmd = subprocess.check_output(f'nmap -sP {subnet}/24', shell=True).decode()
551
 	output = cmd.split('Nmap scan report for ')[1:-1]
552
 	for item in output:
553
 		ip    = item.split('\n')[0]
554
diff --git a/progress.sh b/progress.sh
555
new file mode 100644
556
index 0000000..a090f90
557
--- /dev/null
558
+++ b/progress.sh
559
@@ -0,0 +1,7 @@
560
+PROGRESS='#'
561
+for PERCENT in {1..100}; do
562
+	echo -ne "$PERCENT%\t$PROGRESS\r"
563
+	PROGRESS="$PROGRESS#"
564
+	sleep 0.05
565
+done
566
+echo -e "\n"
567
diff --git a/scales.py b/scales.py
568
deleted file mode 100644
569
index 8cbe94b..0000000
570
--- a/scales.py
571
+++ /dev/null
572
@@ -1,88 +0,0 @@
573
-#!/usr/bin/env python
574
-# guitar scales generator - developed by acidvegas in python (https://acid.vegas/random)
575
-
576
-scales = {
577
-	'algerian'              :  '2131131', # 1 = Half-step | 2 = Whole-step | 3 = Whole-step-Half-step
578
-	'aeolian'               :  '2122122',
579
-	'blues'                 :   '321132',
580
-	'chromatic'             :  '1111111',
581
-	'dorian'                :  '2122212',
582
-	'half_whole_diminished' : '12121212',
583
-	'harmonic_minor'        :  '2122131',
584
-	'ionian'                :  '2212221',
585
-	'locrian'               :  '1221222',
586
-	'lydian'                :  '2221221',
587
-	'major'                 :  '2212221',
588
-	'major_pentatonic'      :    '22323',
589
-	'melodic_minor'         :  '2122221',
590
-	'mixolydian'            :  '2212212',
591
-	'natural_minor'         :  '2122122',
592
-	'persian'               :  '1311231',
593
-	'phrygian'              :  '1222122',
594
-	'whole_half_diminished' : '21212121',
595
-	'whole_tone'            :  '2222222'
596
-}
597
-
598
-def generate_notes(key):
599
-	notes = ['A','A#','B','C','C#','D','D#','E','F','F#','G','G#']
600
-	while notes[0] != key:
601
-		notes.append(notes.pop(0))
602
-	return notes
603
-
604
-def generate_scale(string, scale_notes, full=False):
605
-	notes = generate_notes(string.upper())*2 if full else generate_notes(string.upper())
606
-	notes.append(notes[0])
607
-	for index,note in enumerate(notes):
608
-		if note in scale_notes:
609
-			notes[index] = notes[index].center(5, '-')
610
-		else:
611
-			notes[index] = '-'*5
612
-	return notes
613
-
614
-def get_pattern(pattern):
615
-	new_pattern = list()
616
-	for step in pattern:
617
-		if   step == '1' : new_pattern.append('H')
618
-		elif step == '2' : new_pattern.append('W')
619
-		elif step == '3' : new_pattern.append('WH')
620
-	return ' '.join(new_pattern)
621
-
622
-def scale(type, key):
623
-	last = 0
624
-	notes = generate_notes(key)
625
-	scale_notes = [notes[0],]
626
-	for step in scales[type]:
627
-		last += int(step)
628
-		if last >= len(notes):
629
-			last -= len(notes)
630
-		scale_notes.append(notes[last])
631
-	return scale_notes
632
-
633
-def print_scale(root, type, full=False):
634
-	if root.upper() not in ('A','A#','B','C','C#','D','D#','E','F','F#','G','G#'):
635
-		raise SystemExit('invalid root note')
636
-	elif type.lower() not in scales:
637
-		raise SystemExit('invalid scale type')
638
-	else:
639
-		frets = (24,147) if full else (12,75)
640
-		print(f'{root.upper()} {type.upper()} SCALE'.center(frets[1]))
641
-		print('  ┌' + '┬'.join('─'*5 for x in range(frets[0])) + '┐')
642
-		print('0 │' + '│'.join(str(x).center(5) for x in range(1,frets[0]+1)) + '│')
643
-		print('  ├' + '┼'.join('─'*5 for x in range(frets[0])) + '┤')
644
-		scale_notes = scale(type, root)
645
-		for string in ('eBGDAE'):
646
-			string_notes = generate_scale(string, scale_notes, full)
647
-			print(string + ' │' + '│'.join(note.center(5, '-') for note in string_notes[1:]) + '│')
648
-		print('  └' + '┴'.join('─'*5 for x in range(frets[0])) + '┘')
649
-		print((', '.join(scale_notes) + ' / ' + get_pattern(scales[type])).rjust(frets[1]))
650
-
651
-def print_scales():
652
-	max_key = max(len(x) for x in scales)
653
-	max_value = max(len(get_pattern(scales[x])) for x in scales)
654
-	print('NAME'.ljust(max_key+3) + 'PATTERN'.rjust(max_value))
655
-	for name, pattern in scales.items():
656
-		print(name.ljust(max_key) + ' │ ' + get_pattern(pattern).rjust(max_value))
657
-
658
-# Main
659
-print_scales()
660
-print_scale('F#','major')