mirror of
https://github.com/gasparch/ubuntu-luks-autounlock.git
synced 2025-02-05 12:00:57 +00:00
initial commit
This commit is contained in:
parent
58812f2668
commit
1490d1e858
83
README.md
83
README.md
@ -1,2 +1,81 @@
|
||||
# ubuntu-luks-autounlock
|
||||
Scripts to automatically unlock LUKS encrypted partitions based on machine environment
|
||||
# Ubuntu LUKS auto unlock
|
||||
|
||||
## Do not miss information
|
||||
This is part of educational materials about Ubuntu administration from my site
|
||||
[http://gasparchilingarov.com/](http://gasparchilingarov.com).
|
||||
|
||||
Click link and subscibe to mailing list to start learning today.
|
||||
|
||||
## Purpose
|
||||
|
||||
This script is intended to help unlocking Ubuntu system encrypted disks
|
||||
automatically when it is used in known environment (at home). In all other
|
||||
environments it will still ask for passwords to unlock disks.
|
||||
|
||||
This setup intends to protect system **only from accidental laptop theft**. If you are
|
||||
potential hacking target - do not use it, your data may be at risk.
|
||||
|
||||
Right now scripts take into account:
|
||||
* MAC address of your Wifi network
|
||||
* information from your external display
|
||||
|
||||
If you use it without external monitor (it will pick up your build-in monitor
|
||||
information) there is a risk someone can guess/scan your Wifi and find out
|
||||
MAC address and be able to generate correct decryption key, so do not use it.
|
||||
|
||||
## Compatibility
|
||||
|
||||
Scripts are tested on Ubuntu 16.04 64-bit only. Use it on your own risk on other systems.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Copy files from repository to corresponding directories on your Ubuntu system.
|
||||
|
||||
Run `/usr/local/bin/autounlock_install_dependency.sh` to install necessary
|
||||
dependencies.
|
||||
|
||||
Configure your Wifi interface (most probably "wlan0"), Wifi network name and
|
||||
LUKS partition key slot number in `/usr/local/etc/auto_unlock.conf`.
|
||||
|
||||
You can run `cryptsetup luksDump /dev/sdXXXX` to check which slots are free on
|
||||
your encrypted partitions. LUKS partition can have up to 8 keys for
|
||||
decyphering. Key slot `0` is used by default for your manually entered password
|
||||
and cannot be used to auto-unlock.
|
||||
|
||||
Run `/usr/local/bin/autounlock_install_key.sh` to add or update keys on all
|
||||
LUKS partitions defined in `/etc/crypttab`. Follow script prompts to finish setup.
|
||||
|
||||
## Add boot scripts
|
||||
|
||||
After adding keys to partitions you need to add correspondig scripts to do auto
|
||||
unlock into initramfs.
|
||||
|
||||
You need to have scripts in corresponding directories under `/etc/initramfs-tools/`.
|
||||
|
||||
Run `update-initramfs -k all -u` to update all kernel images.
|
||||
|
||||
|
||||
## Try it out
|
||||
|
||||
Reboot :) If everything went smoothly - your system will boot without asking passwords at all.
|
||||
|
||||
Try disconnecting external monitor or turning off Wifi and rebooting again to
|
||||
confirm that it asks for password to decode partitions.
|
||||
|
||||
|
||||
## Removing extra keys
|
||||
|
||||
If you want to remove auto-unlock keys use `cryptsetup luksKillSlot /dev/sdaXXXX KEYSLOT`.
|
||||
|
||||
KEYSLOT should be same slot you used while setting up auto-unlock keys. Do not
|
||||
delete occasionally other slots, as you may be locked out of your system.
|
||||
|
||||
## Extra sources of information
|
||||
|
||||
Adding extra information sources is pretty straightforward - just keep it in
|
||||
sync between `etc/initramfs-tools/scripts/local-top/cryptroot-prepare:gather_key_information()`
|
||||
and `usr/local/bin/autounlock_install_key.sh`. If you need extra
|
||||
binaries/drivers in initramfs - add them into
|
||||
`etc/initramfs-tools/hooks/prepare_auto_unlock_deps` script.
|
||||
|
||||
|
64
etc/initramfs-tools/hooks/prepare_auto_unlock_deps
Executable file
64
etc/initramfs-tools/hooks/prepare_auto_unlock_deps
Executable file
@ -0,0 +1,64 @@
|
||||
#!/bin/sh
|
||||
PREREQ=""
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
|
||||
# These prerequisites are provided by the read-edid package.
|
||||
COPY_EXEC_LIST="/usr/bin/get-edid /usr/bin/parse-edid"
|
||||
|
||||
# These prerequisites are provided by the base system.
|
||||
COPY_EXEC_LIST="$COPY_EXEC_LIST /sbin/iwlist"
|
||||
|
||||
# Explicitly specify all kernel modules because automatic dependency resolution
|
||||
# is unreliable on many systems.
|
||||
MANUAL_ADD_MODULES_LIST="iwlwifi iwlmvm iwldvm mac80211 cfg80211"
|
||||
|
||||
echo "Adding $MANUAL_ADD_MODULES_LIST for network detection"
|
||||
|
||||
# Generic result code.
|
||||
RC=0
|
||||
|
||||
case $1 in
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
for ii in $COPY_EXEC_LIST
|
||||
do
|
||||
if [ ! -x "$ii" ]
|
||||
then
|
||||
echo "Error: $ii is not executable."
|
||||
RC=2
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$RC" -ne 0 ]
|
||||
then
|
||||
exit "$RC"
|
||||
fi
|
||||
|
||||
. /usr/share/initramfs-tools/hook-functions
|
||||
|
||||
for ii in $COPY_EXEC_LIST
|
||||
do
|
||||
copy_exec "$ii"
|
||||
done
|
||||
|
||||
for ii in $MANUAL_ADD_MODULES_LIST
|
||||
do
|
||||
manual_add_modules "$ii"
|
||||
done
|
||||
|
||||
mkdir -p ${DESTDIR}/lib/firmware
|
||||
for ii in `find /lib/firmware/ -name 'iwlwifi-*'`
|
||||
do
|
||||
cp -p $ii ${DESTDIR}/lib/firmware/
|
||||
done
|
||||
|
||||
mkdir -p ${DESTDIR}/etc
|
||||
cp -p /usr/local/etc/auto_unlock.conf ${DESTDIR}/etc/auto_unlock.conf
|
||||
|
338
etc/initramfs-tools/scripts/local-top/cryptroot-prepare
Executable file
338
etc/initramfs-tools/scripts/local-top/cryptroot-prepare
Executable file
@ -0,0 +1,338 @@
|
||||
#!/bin/sh
|
||||
|
||||
PREREQ=""
|
||||
|
||||
#
|
||||
# Standard initramfs preamble
|
||||
#
|
||||
prereqs()
|
||||
{
|
||||
echo "$PREREQ"
|
||||
}
|
||||
|
||||
case $1 in
|
||||
prereqs)
|
||||
prereqs
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# source for log_*_msg() functions, see LP: #272301
|
||||
. /scripts/functions
|
||||
|
||||
#
|
||||
# Helper functions
|
||||
#
|
||||
message()
|
||||
{
|
||||
if [ -x /bin/plymouth ] && plymouth --ping; then
|
||||
plymouth message --text="$@"
|
||||
else
|
||||
echo "$@" >&2
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
udev_settle()
|
||||
{
|
||||
# Wait for udev to be ready, see https://launchpad.net/bugs/85640
|
||||
if command -v udevadm >/dev/null 2>&1; then
|
||||
udevadm settle --timeout=30
|
||||
elif command -v udevsettle >/dev/null 2>&1; then
|
||||
udevsettle --timeout=30
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
parse_options()
|
||||
{
|
||||
local cryptopts
|
||||
cryptopts="$1"
|
||||
|
||||
if [ -z "$cryptopts" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Defaults
|
||||
cryptcipher=aes-cbc-essiv:sha256
|
||||
cryptsize=256
|
||||
crypthash=ripemd160
|
||||
crypttarget=cryptroot
|
||||
cryptsource=""
|
||||
cryptheader=""
|
||||
cryptlvm=""
|
||||
cryptkeyscript=""
|
||||
cryptkey="" # This is only used as an argument to an eventual keyscript
|
||||
crypttries=3
|
||||
crypttcrypt=""
|
||||
cryptrootdev=""
|
||||
cryptdiscard=""
|
||||
CRYPTTAB_OPTIONS=""
|
||||
|
||||
local IFS=" ,"
|
||||
for x in $cryptopts; do
|
||||
case $x in
|
||||
hash=*)
|
||||
crypthash=${x#hash=}
|
||||
;;
|
||||
size=*)
|
||||
cryptsize=${x#size=}
|
||||
;;
|
||||
cipher=*)
|
||||
cryptcipher=${x#cipher=}
|
||||
;;
|
||||
target=*)
|
||||
crypttarget=${x#target=}
|
||||
export CRYPTTAB_NAME="$crypttarget"
|
||||
;;
|
||||
source=*)
|
||||
cryptsource=${x#source=}
|
||||
if [ ${cryptsource#UUID=} != $cryptsource ]; then
|
||||
cryptsource="/dev/disk/by-uuid/${cryptsource#UUID=}"
|
||||
elif [ ${cryptsource#LABEL=} != $cryptsource ]; then
|
||||
cryptsource="/dev/disk/by-label/${cryptsource#LABEL=}"
|
||||
fi
|
||||
export CRYPTTAB_SOURCE="$cryptsource"
|
||||
;;
|
||||
header=*)
|
||||
cryptheader=${x#header=}
|
||||
if [ ! -e "$cryptheader" ] && [ -e "/conf/conf.d/cryptheader/$cryptheader" ]; then
|
||||
cryptheader="/conf/conf.d/cryptheader/$cryptheader"
|
||||
fi
|
||||
export CRYPTTAB_HEADER="$cryptheader"
|
||||
;;
|
||||
lvm=*)
|
||||
cryptlvm=${x#lvm=}
|
||||
;;
|
||||
keyscript=*)
|
||||
cryptkeyscript=${x#keyscript=}
|
||||
;;
|
||||
key=*)
|
||||
if [ "${x#key=}" != "none" ]; then
|
||||
cryptkey=${x#key=}
|
||||
fi
|
||||
export CRYPTTAB_KEY="$cryptkey"
|
||||
;;
|
||||
tries=*)
|
||||
crypttries="${x#tries=}"
|
||||
case "$crypttries" in
|
||||
*[![:digit:].]*)
|
||||
crypttries=3
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
tcrypt)
|
||||
crypttcrypt="yes"
|
||||
;;
|
||||
rootdev)
|
||||
cryptrootdev="yes"
|
||||
;;
|
||||
discard)
|
||||
cryptdiscard="yes"
|
||||
;;
|
||||
esac
|
||||
PARAM="${x%=*}"
|
||||
if [ "$PARAM" = "$x" ]; then
|
||||
VALUE="yes"
|
||||
else
|
||||
VALUE="${x#*=}"
|
||||
fi
|
||||
CRYPTTAB_OPTIONS="$CRYPTTAB_OPTIONS $PARAM"
|
||||
eval export CRYPTTAB_OPTION_$PARAM="\"$VALUE\""
|
||||
done
|
||||
export CRYPTTAB_OPTIONS
|
||||
|
||||
if [ -z "$cryptsource" ]; then
|
||||
message "cryptsetup: source parameter missing"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
activate_vg()
|
||||
{
|
||||
# Sanity checks
|
||||
if [ ! -x /sbin/lvm ]; then
|
||||
message "cryptsetup: lvm is not available"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Detect and activate available volume groups
|
||||
/sbin/lvm vgscan
|
||||
/sbin/lvm vgchange -a y --sysinit
|
||||
return $?
|
||||
}
|
||||
|
||||
setup_mapping()
|
||||
{
|
||||
local opts count cryptopen cryptremove NEWROOT
|
||||
opts="$1"
|
||||
|
||||
if [ -z "$opts" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
parse_options "$opts" || return 1
|
||||
|
||||
# The same target can be specified multiple times
|
||||
# e.g. root and resume lvs-on-lvm-on-crypto
|
||||
if [ -e "/dev/mapper/$crypttarget" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
modprobe -q dm_crypt
|
||||
|
||||
# Make sure the cryptsource device is available
|
||||
if [ ! -e $cryptsource ]; then
|
||||
activate_vg
|
||||
fi
|
||||
|
||||
# If the encrypted source device hasn't shown up yet, give it a
|
||||
# little while to deal with removable devices
|
||||
|
||||
# the following lines below have been taken from
|
||||
# /usr/share/initramfs-tools/scripts/local, as suggested per
|
||||
# https://launchpad.net/bugs/164044
|
||||
if [ ! -e "$cryptsource" ]; then
|
||||
log_begin_msg "Waiting for encrypted source device..."
|
||||
|
||||
# Default delay is 180s
|
||||
if [ -z "${ROOTDELAY}" ]; then
|
||||
slumber=180
|
||||
else
|
||||
slumber=${ROOTDELAY}
|
||||
fi
|
||||
|
||||
slumber=$(( ${slumber} * 10 ))
|
||||
while [ ! -e "$cryptsource" ]; do
|
||||
# retry for LVM devices every 10 seconds
|
||||
if [ ${slumber} -eq $(( ${slumber}/100*100 )) ]; then
|
||||
activate_vg
|
||||
fi
|
||||
|
||||
/bin/sleep 0.1
|
||||
slumber=$(( ${slumber} - 1 ))
|
||||
[ ${slumber} -gt 0 ] || break
|
||||
done
|
||||
|
||||
if [ ${slumber} -gt 0 ]; then
|
||||
log_end_msg 0
|
||||
else
|
||||
log_end_msg 1 || true
|
||||
fi
|
||||
fi
|
||||
udev_settle
|
||||
|
||||
# We've given up, but we'll let the user fix matters if they can
|
||||
if [ ! -e "${cryptsource}" ]; then
|
||||
echo " ALERT! ${cryptsource} does not exist."
|
||||
echo " Check cryptopts=source= bootarg: cat /proc/cmdline"
|
||||
echo " or missing modules, devices: cat /proc/modules; ls /dev"
|
||||
panic -r "Dropping to a shell. Will skip ${cryptsource} if you can't fix."
|
||||
fi
|
||||
|
||||
if [ ! -e "${cryptsource}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
||||
# Prepare commands
|
||||
cryptopen="/sbin/cryptsetup -T 1"
|
||||
if [ "$cryptdiscard" = "yes" ]; then
|
||||
cryptopen="$cryptopen --allow-discards"
|
||||
fi
|
||||
if [ -n "$cryptheader" ]; then
|
||||
cryptopen="$cryptopen --header=$cryptheader"
|
||||
fi
|
||||
if /sbin/cryptsetup isLuks ${cryptheader:-$cryptsource} >/dev/null 2>&1; then
|
||||
cryptopen="$cryptopen open --type luks $cryptsource $crypttarget --key-file=-"
|
||||
elif [ "$crypttcrypt" = "yes" ]; then
|
||||
cryptopen="$cryptopen open --type tcrypt $cryptsource $crypttarget"
|
||||
else
|
||||
cryptopen="$cryptopen -c $cryptcipher -s $cryptsize -h $crypthash open --type plain $cryptsource $crypttarget --key-file=-"
|
||||
fi
|
||||
cryptremove="/sbin/cryptsetup remove $crypttarget"
|
||||
NEWROOT="/dev/mapper/$crypttarget"
|
||||
|
||||
# Try to get a satisfactory password $crypttries times
|
||||
count=0
|
||||
crypttries=1
|
||||
while [ $crypttries -le 0 ] || [ $count -lt $crypttries ]; do
|
||||
export CRYPTTAB_TRIED="$count"
|
||||
count=$(( $count + 1 ))
|
||||
|
||||
cryptkeyscript="/bin/cat"
|
||||
cryptkey="$LOCK_FILE"
|
||||
|
||||
if [ ! -e "$NEWROOT" ]; then
|
||||
if ! crypttarget="$crypttarget" cryptsource="$cryptsource" \
|
||||
$cryptkeyscript "$cryptkey" | $cryptopen; then
|
||||
message "autounlock: cryptsetup failed, gathred bad key?"
|
||||
break
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -e "$NEWROOT" ]; then
|
||||
message "cryptsetup: unknown error setting up device mapping"
|
||||
return 1
|
||||
fi
|
||||
|
||||
message "cryptsetup: $crypttarget set up successfully"
|
||||
break
|
||||
done
|
||||
|
||||
if [ $crypttries -gt 0 ] && [ $count -gt $crypttries ]; then
|
||||
message "cryptsetup: maximum number of tries exceeded for $crypttarget"
|
||||
return 1
|
||||
fi
|
||||
|
||||
udev_settle
|
||||
return 0
|
||||
}
|
||||
|
||||
# Look into phisical environment around and gather information
|
||||
gather_key_information()
|
||||
{
|
||||
if [ ! -f "/etc/auto_unlock.conf" ]; then
|
||||
log_failure_msg "Auto-unlock does not have config in initramfs"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
. /etc/auto_unlock.conf
|
||||
udev_settle
|
||||
|
||||
# gather local Wifi MAC
|
||||
ifconfig $WIFI_INTERFACE up
|
||||
WIFI_MAC=`iwlist scanning 2>/dev/null | egrep 'Address|ESSID' | grep -B1 'ESSID:"'"${WIFI_NETWORK}"'"' | awk -F'Address: ' '/Address/ {print $2}'`
|
||||
|
||||
# gather external monitor EDID info
|
||||
EDID_LINES=`get-edid 2>/dev/null | parse-edid | egrep 'Identifier|ModelName|VendorName|Manufactured week|DisplaySize' | LANG=C sort`
|
||||
|
||||
echo -e "$WIFI_MAC\n$EDID_LINES" > $LOCK_FILE
|
||||
}
|
||||
|
||||
finish()
|
||||
{
|
||||
rm -f $LOCK_FILE
|
||||
}
|
||||
|
||||
#
|
||||
# Begin real processing
|
||||
#
|
||||
|
||||
# Acquire potential key from connected devices
|
||||
|
||||
LOCK_FILE=/conf/autounlock.key
|
||||
trap finish EXIT
|
||||
|
||||
gather_key_information
|
||||
|
||||
# Do we have any settings from the /conf/conf.d/cryptroot file?
|
||||
if [ -r /conf/conf.d/cryptroot ]; then
|
||||
while read mapping <&3; do
|
||||
setup_mapping "$mapping" 3<&-
|
||||
done 3< /conf/conf.d/cryptroot
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
3
usr/local/bin/autounlock_install_dependency.sh
Executable file
3
usr/local/bin/autounlock_install_dependency.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
apt install read-edid
|
100
usr/local/bin/autounlock_install_key.sh
Executable file
100
usr/local/bin/autounlock_install_key.sh
Executable file
@ -0,0 +1,100 @@
|
||||
#!/bin/bash
|
||||
|
||||
mkdir -p /run/keytemp
|
||||
LOCK_FILE="/run/keytemp/lock_key"
|
||||
|
||||
function finish {
|
||||
rm -f $LOCK_FILE
|
||||
}
|
||||
trap finish EXIT
|
||||
|
||||
|
||||
echo "Generates key based on your Wifi MAC address and infromation from your external monitor"
|
||||
echo "If you do not have external monitor attached, please turn it off in /usr/local/etc/auto_unlock.conf"
|
||||
echo "It can decrease security of auto unlock because Wifi MAC is visible to everyone in proximity of your location."
|
||||
|
||||
. /usr/local/etc/auto_unlock.conf
|
||||
|
||||
if [ "$KEYSLOT" = "0" ]; then
|
||||
echo "Cannot use key slot 0"
|
||||
exit 10
|
||||
fi
|
||||
|
||||
echo "Looking up AP MAC for Wifi network $WIFI_NETWORK"
|
||||
|
||||
WIFI_MAC=`iwlist scanning 2>/dev/null | egrep 'Address|ESSID' | grep -B1 'ESSID:"'"${WIFI_NETWORK}"'"' | awk -F'Address: ' '/Address/ {print $2}'`
|
||||
|
||||
echo "Found MAC == |$WIFI_MAC| "
|
||||
|
||||
EDID_LINES=`get-edid 2>/dev/null | parse-edid | egrep 'Identifier|ModelName|VendorName|Manufactured week|DisplaySize' | LANG=C sort `
|
||||
|
||||
echo "Gathered display information"
|
||||
echo -e "--------\n${EDID_LINES}\n-----------\n"
|
||||
|
||||
echo "Please verify that Wifi MAC of Access Point and display information are valid"
|
||||
echo "Especially verify that your external display is recognized, not build-in one"
|
||||
|
||||
echo "Type in YES to set-up LUKS key based on information above"
|
||||
read ANSWER
|
||||
|
||||
if [ "$ANSWER" != "YES" ]; then
|
||||
echo "Exiting without setup"
|
||||
exit 5
|
||||
fi
|
||||
|
||||
echo -e "$WIFI_MAC\n$EDID_LINES" > $LOCK_FILE
|
||||
echo "Checksum of lockfile $(md5sum $LOCK_FILE)"
|
||||
echo "Stored lock file in $LOCK_FILE, please delete it manually if you cancel script execution"
|
||||
|
||||
echo "Parsing /etc/crypttab"
|
||||
|
||||
for TEXT in $(awk '/^..*$/ {print $1 ":" $2}' /etc/crypttab); do
|
||||
|
||||
NAME=`echo "$TEXT" | cut -d: -f1`
|
||||
DEVICE=`echo "$TEXT" | cut -d: -f2`
|
||||
|
||||
case $DEVICE in
|
||||
/dev/*) ;;
|
||||
UUID=*) UUID=${DEVICE##UUID=}
|
||||
DEVICE=$(blkid -U "$UUID")
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$DEVICE" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "found partition $DEVICE for $NAME"
|
||||
|
||||
if [ ! -b $DEVICE ]; then
|
||||
echo "Cannot work on $DEVICE, not a block device"
|
||||
continue
|
||||
fi
|
||||
|
||||
SLOTS=`cryptsetup luksDump $DEVICE | grep '^Key Slot'`
|
||||
SLOT_USAGE=`echo "$SLOTS" | grep "Key Slot $KEYSLOT"`
|
||||
|
||||
echo -e "slots usage for $DEVICE\n------\n${SLOTS}\n---------\n"
|
||||
|
||||
SLOT_OK=
|
||||
case "$SLOT_USAGE" in
|
||||
*DISABLED) SLOT_OK=1 ;;
|
||||
*ENABLED)
|
||||
echo "Slot $KEYSLOT is used for device $NAME $DEVICE"
|
||||
echo "Do you want to override it? Type YES to override"
|
||||
read ANSWER
|
||||
if [ "$ANSWER" != "YES" ]; then
|
||||
echo "Not overriding ..."
|
||||
continue
|
||||
fi
|
||||
cryptsetup luksKillSlot $DEVICE $KEYSLOT
|
||||
SLOT_OK=1
|
||||
esac
|
||||
|
||||
if [ "$SLOT_OK" = "1" ]; then
|
||||
cryptsetup luksAddKey --key-slot $KEYSLOT $DEVICE $LOCK_FILE
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
|
3
usr/local/etc/auto_unlock.conf
Normal file
3
usr/local/etc/auto_unlock.conf
Normal file
@ -0,0 +1,3 @@
|
||||
WIFI_INTERFACE="wlan0"
|
||||
WIFI_NETWORK="YOUR_NETWORK_NAME"
|
||||
KEYSLOT=7
|
Loading…
Reference in New Issue
Block a user