From 8d2e883c5f4668d20843bcee1f08d6e564b6af9d Mon Sep 17 00:00:00 2001 From: Werner Date: Sun, 9 Jun 2024 20:23:57 +0200 Subject: [PATCH 01/13] Create users_sync.sh Initial commit. Untested. Probably broken. Do not use...yet --- utils/users_sync.sh | 101 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 utils/users_sync.sh diff --git a/utils/users_sync.sh b/utils/users_sync.sh new file mode 100644 index 00000000..1bc2636f --- /dev/null +++ b/utils/users_sync.sh @@ -0,0 +1,101 @@ +#!/bin/bash + + +### CONFIG +# where are the user directories? +# NO trailing slash! +# the owner of the parent directory must be "root"! +USERPATH=/var/www/users + +# which group is used to catch and jail users into their sftp chroot? +SFTPGROUP=sftponly + + + +### DO NOT EDIT BELOW! ### + +### TODO +# add blocklist/keeplist +# add update/refresh keys on existing user +# make sure concealed members are grabbed as well: https://docs.github.com/en/rest/orgs/members?apiVersion=2022-11-28#list-organization-members + + +# check for root +if [ "$EUID" -ne 0 ]; then + echo "Please run as root" + exit 1 +fi + +# check for existing sftp group +if ! getent group sftponly &> /dev/null +then + echo "\"$SFTPGROUP\" group does not exist. Use \"groupadd $SFTPGROUP\" to add." + echo "" + echo "Add this to your \"sshd_config\" if not done already." + echo "" + echo "Match Group $SFTPGROUP" + echo " ChrootDirectory $PATUSERH/%u" + echo " ForceCommand internal-sftp" + echo " AllowTcpForwarding no" + exit 1 +fi + + + +# grab a list of current remote org members and make it comparable +ORGMEMBERS=$(curl -s https://api.github.com/orgs/armbian/members | jq -r ".[].login") +# Grab a list of local directories and make it comparable +# We assume that existing directory means locally existing user as well +LOCALMEMBERS=$(echo -n "`ls members/`") +LOCALMEMBERS_COMP=$(echo -n "`ls members/`" | sed 's/\ /|/g' |sed -r 's/^/\(/' |sed -r 's/$/\)/') + + +# loop through remote org members and add if not existing +for i in $ORGMEMBERS; do + + if ! [[ $i =~ $LOCALMEMBERS_COMP ]]; then # skip locally already existing users + + # create local user and directory + echo " $i - no local directory found. Creating..." + if ! useradd -m -s /bin/bash -G $SFTPGROUP -d $USERPATH/"$i" "$i" + then + echo "$i's directory could not be created for whatever reason" + exit 1 + fi + echo "$i directory created" + + # grab ssh keys and put into user's .ssh/authorized_keys file + echo "Trying to grab ssh keys" + mkdir -p $USERPATH/"$i"/.ssh + curl -s https://github.com/"$i".keys > "$USERPATH"/"$i"/.ssh/authorized_keys + chown -R "$i":$SFTPGROUP "$USERPATH"/"$i"/.ssh + chmod 600 $USERPATH/"$i"/.ssh/authorized_keys + + # Check if grabbed stuff are actual ssh keys + CHECK_KEYS=$(cat $USERPATH/"$i"/.ssh/authorized_keys|grep -c -E "^ssh") + if [[ $CHECK_KEYS != 0 ]]; then + echo "$i - $CHECK_KEYS key/s for $i imported" + else + echo "$i - Either grabbing failed or $i does not have ssh key on git" + echo "$i won't be able to login" + rm $USERPATH/"$i"/.ssh/authorized_keys + fi + + else + echo "$i - local directory found. Skipping..." + # TODO: update ssh keys here + fi +done + +# remove local users not exsting in remote org +ORGMEMBERS_COMP=$(echo -n "`curl -s https://api.github.com/orgs/armbian/members | jq -r ".[].login"`" | sed 's/\ /|/g' |sed -r 's/^/\(/' |sed -r 's/$/\)/') + +for i in $LOCALMEMBERS; do + + if ! [[ $i =~ $ORGMEMBERS_COMP ]]; then # compare local user against list of remote org members. If not found carry on + echo "$i is not in the list of remote org members. Removing its legacy..." + userdel --remove "$i" + else + echo "$i is still member of remote org. Skipping..." + fi +done From 5e5ffe17bae53c753935c1690a63f18db94fb7b5 Mon Sep 17 00:00:00 2001 From: Werner Date: Sun, 9 Jun 2024 20:25:25 +0200 Subject: [PATCH 02/13] Create README.md --- utils/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 utils/README.md diff --git a/utils/README.md b/utils/README.md new file mode 100644 index 00000000..8ac23c5e --- /dev/null +++ b/utils/README.md @@ -0,0 +1 @@ +`users_sync.sh` has been created to automatically give members of the Armbian organization access to https://users.armbian.com (WIP) From 1345b0cf04f4f205724ca9db184222c352bae018 Mon Sep 17 00:00:00 2001 From: Werner Date: Tue, 11 Jun 2024 06:16:40 +0200 Subject: [PATCH 03/13] Add blocklist and token support --- utils/users_sync.sh | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/utils/users_sync.sh b/utils/users_sync.sh index 1bc2636f..21486ad3 100644 --- a/utils/users_sync.sh +++ b/utils/users_sync.sh @@ -5,12 +5,20 @@ # where are the user directories? # NO trailing slash! # the owner of the parent directory must be "root"! +# configure nginx accordingly USERPATH=/var/www/users # which group is used to catch and jail users into their sftp chroot? SFTPGROUP=sftponly +# classic token from any organization member with "read:org" permission +TOKEN=xxxxxxxxxxxxxxxx +# the organization you want to read members from +ORG=armbian + +# Users that shall not get access +BLOCKLIST='armbianworker|examplemember1|examplemember2' ### DO NOT EDIT BELOW! ### @@ -42,12 +50,18 @@ fi -# grab a list of current remote org members and make it comparable -ORGMEMBERS=$(curl -s https://api.github.com/orgs/armbian/members | jq -r ".[].login") -# Grab a list of local directories and make it comparable +# grab a list of current remote org members, filter blocked ones +ORGMEMBERS=$(curl -L -s \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $TOKEN" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/orgs/$ORG/members | jq -r ".[].login" \ + | grep -v -E -- "$BLOCKLIST" ) +# Grab a list of local directories... # We assume that existing directory means locally existing user as well -LOCALMEMBERS=$(echo -n "`ls members/`") -LOCALMEMBERS_COMP=$(echo -n "`ls members/`" | sed 's/\ /|/g' |sed -r 's/^/\(/' |sed -r 's/$/\)/') +LOCALMEMBERS=$(echo -n "`ls $USERPATH`") +# ...and make it comparable for shell +LOCALMEMBERS_COMP=$(echo -n "`ls $USERPATH`" | sed 's/\ /|/g' |sed -r 's/^/\(/' |sed -r 's/$/\)/') # loop through remote org members and add if not existing From 5188346e55f4be806dc4267b8fa480b5873c1514 Mon Sep 17 00:00:00 2001 From: Werner Date: Tue, 11 Jun 2024 06:41:56 +0200 Subject: [PATCH 04/13] fix comparison --- utils/users_sync.sh | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/utils/users_sync.sh b/utils/users_sync.sh index 21486ad3..6085ea5a 100644 --- a/utils/users_sync.sh +++ b/utils/users_sync.sh @@ -1,6 +1,12 @@ #!/bin/bash +### TODO +# add blocklist/keeplist +# add update/refresh keys on existing user +# make sure concealed members are grabbed as well: https://docs.github.com/en/rest/orgs/members?apiVersion=2022-11-28#list-organization-members + + ### CONFIG # where are the user directories? # NO trailing slash! @@ -12,22 +18,20 @@ USERPATH=/var/www/users SFTPGROUP=sftponly # classic token from any organization member with "read:org" permission -TOKEN=xxxxxxxxxxxxxxxx +TOKEN=xxxxxxxxxx # the organization you want to read members from ORG=armbian # Users that shall not get access BLOCKLIST='armbianworker|examplemember1|examplemember2' +### END CONFIG -### DO NOT EDIT BELOW! ### -### TODO -# add blocklist/keeplist -# add update/refresh keys on existing user -# make sure concealed members are grabbed as well: https://docs.github.com/en/rest/orgs/members?apiVersion=2022-11-28#list-organization-members +### DO NOT EDIT BELOW! ### +### CHECKS # check for root if [ "$EUID" -ne 0 ]; then echo "Please run as root" @@ -47,7 +51,7 @@ then echo " AllowTcpForwarding no" exit 1 fi - +### END CHECKS # grab a list of current remote org members, filter blocked ones @@ -59,15 +63,15 @@ ORGMEMBERS=$(curl -L -s \ | grep -v -E -- "$BLOCKLIST" ) # Grab a list of local directories... # We assume that existing directory means locally existing user as well -LOCALMEMBERS=$(echo -n "`ls $USERPATH`") -# ...and make it comparable for shell -LOCALMEMBERS_COMP=$(echo -n "`ls $USERPATH`" | sed 's/\ /|/g' |sed -r 's/^/\(/' |sed -r 's/$/\)/') - +cd $USERPATH +LOCALMEMBERS=$(echo -n "`ls -d */`" | sed 's/\///g') +# ...and make it comparable for shell (remove trailing slash, replace space with |, add round brackets) +LOCALMEMBERS_COMPARE=$(echo -n "`ls -d */`" | sed 's/\///g' | tr '\n' '|' | sed -r 's/^/\(/' | sed -r 's/$/\)/') # loop through remote org members and add if not existing for i in $ORGMEMBERS; do - if ! [[ $i =~ $LOCALMEMBERS_COMP ]]; then # skip locally already existing users + if ! [[ $i =~ $LOCALMEMBERS_COMPARE ]]; then # skip locally already existing users # create local user and directory echo " $i - no local directory found. Creating..." @@ -85,7 +89,9 @@ for i in $ORGMEMBERS; do chown -R "$i":$SFTPGROUP "$USERPATH"/"$i"/.ssh chmod 600 $USERPATH/"$i"/.ssh/authorized_keys - # Check if grabbed stuff are actual ssh keys + # Check if grabbed stuff are actual ssh keys. + # curl response for members w/o keys is "not found" but exit code is still 0 + # so this needs to be worked around CHECK_KEYS=$(cat $USERPATH/"$i"/.ssh/authorized_keys|grep -c -E "^ssh") if [[ $CHECK_KEYS != 0 ]]; then echo "$i - $CHECK_KEYS key/s for $i imported" @@ -102,12 +108,17 @@ for i in $ORGMEMBERS; do done # remove local users not exsting in remote org -ORGMEMBERS_COMP=$(echo -n "`curl -s https://api.github.com/orgs/armbian/members | jq -r ".[].login"`" | sed 's/\ /|/g' |sed -r 's/^/\(/' |sed -r 's/$/\)/') +ORGMEMBERS_COMPARE=$(echo -n "`curl -L -s \ + -H "Accept: application/vnd.github+json" \ + -H "Authorization: Bearer $TOKEN" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/orgs/$ORG/members | jq -r ".[].login"`" \ + | sed 's/\ /|/g' |sed -r 's/^/\(/' |sed -r 's/$/\)/') for i in $LOCALMEMBERS; do - if ! [[ $i =~ $ORGMEMBERS_COMP ]]; then # compare local user against list of remote org members. If not found carry on - echo "$i is not in the list of remote org members. Removing its legacy..." + if ! [[ $i =~ $ORGMEMBERS_COMPARE ]]; then # compare local user against list of remote org members. If not found carry on + echo "$i is not or no longer in the list of remote org members. Removing its legacy..." userdel --remove "$i" else echo "$i is still member of remote org. Skipping..." From e0e1baa9bc773eb50c03e45bdc9d344a014b1a88 Mon Sep 17 00:00:00 2001 From: Werner Date: Tue, 11 Jun 2024 07:32:45 +0200 Subject: [PATCH 05/13] shellcheck, token validation, texts --- utils/users_sync.sh | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/utils/users_sync.sh b/utils/users_sync.sh index 6085ea5a..7711a104 100644 --- a/utils/users_sync.sh +++ b/utils/users_sync.sh @@ -18,7 +18,7 @@ USERPATH=/var/www/users SFTPGROUP=sftponly # classic token from any organization member with "read:org" permission -TOKEN=xxxxxxxxxx +TOKEN=xxxxxxxxx # the organization you want to read members from ORG=armbian @@ -32,9 +32,18 @@ BLOCKLIST='armbianworker|examplemember1|examplemember2' ### CHECKS +# validate token +RESPONSE=$(curl -sS -f -I -H "Authorization: token $TOKEN" https://api.github.com | grep -i x-oauth-scopes |grep -c read:org) +if [[ $RESPONSE != 1 ]]; then + echo "Token invalid or lacking permission." + echo "Exiting..." + exit 1 +fi + # check for root if [ "$EUID" -ne 0 ]; then echo "Please run as root" + echo "Exiting..." exit 1 fi @@ -49,24 +58,34 @@ then echo " ChrootDirectory $PATUSERH/%u" echo " ForceCommand internal-sftp" echo " AllowTcpForwarding no" + echo "" + echo "Exiting..." exit 1 fi ### END CHECKS # grab a list of current remote org members, filter blocked ones +echo "Grabbing a list of all current members of \"$ORG\"." +echo "Excluded by blocklist are \"$BLOCKLIST\"." ORGMEMBERS=$(curl -L -s \ -H "Accept: application/vnd.github+json" \ -H "Authorization: Bearer $TOKEN" \ -H "X-GitHub-Api-Version: 2022-11-28" \ https://api.github.com/orgs/$ORG/members | jq -r ".[].login" \ | grep -v -E -- "$BLOCKLIST" ) + # Grab a list of local directories... # We assume that existing directory means locally existing user as well -cd $USERPATH -LOCALMEMBERS=$(echo -n "`ls -d */`" | sed 's/\///g') -# ...and make it comparable for shell (remove trailing slash, replace space with |, add round brackets) -LOCALMEMBERS_COMPARE=$(echo -n "`ls -d */`" | sed 's/\///g' | tr '\n' '|' | sed -r 's/^/\(/' | sed -r 's/$/\)/') +cd $USERPATH || exit 1 +LOCALMEMBERS=$(echo -n "`ls -d -- */`" | sed 's/\///g' | tr '\n' ' ') +echo "Already existing members at \"$USERPATH\": \"$LOCALMEMBERS\"." +# ...and make it comparable for shell (remove trailing slash, replace newline with | and add round brackets) +LOCALMEMBERS_COMPARE=$(echo -n "`ls -d -- */`" | sed 's/\///g' | tr '\n' '|' | sed -r 's/^/\(/' | sed -r 's/$/\)/') + +# DEBUG +exit 0 +# END DEBUG # loop through remote org members and add if not existing for i in $ORGMEMBERS; do @@ -75,7 +94,7 @@ for i in $ORGMEMBERS; do # create local user and directory echo " $i - no local directory found. Creating..." - if ! useradd -m -s /bin/bash -G $SFTPGROUP -d $USERPATH/"$i" "$i" + if ! useradd -m -s /bin/bash -G "$SFTPGROUP" -d "$USERPATH"/"$i" "$i" then echo "$i's directory could not be created for whatever reason" exit 1 @@ -84,21 +103,21 @@ for i in $ORGMEMBERS; do # grab ssh keys and put into user's .ssh/authorized_keys file echo "Trying to grab ssh keys" - mkdir -p $USERPATH/"$i"/.ssh + mkdir -p "$USERPATH"/"$i"/.ssh curl -s https://github.com/"$i".keys > "$USERPATH"/"$i"/.ssh/authorized_keys - chown -R "$i":$SFTPGROUP "$USERPATH"/"$i"/.ssh - chmod 600 $USERPATH/"$i"/.ssh/authorized_keys + chown -R "$i":"$SFTPGROUP" "$USERPATH"/"$i"/.ssh + chmod 600 "$USERPATH"/"$i"/.ssh/authorized_keys # Check if grabbed stuff are actual ssh keys. # curl response for members w/o keys is "not found" but exit code is still 0 # so this needs to be worked around - CHECK_KEYS=$(cat $USERPATH/"$i"/.ssh/authorized_keys|grep -c -E "^ssh") + CHECK_KEYS=$(grep -c -E "^ssh" "$USERPATH"/"$i"/.ssh/authorized_keys) if [[ $CHECK_KEYS != 0 ]]; then echo "$i - $CHECK_KEYS key/s for $i imported" else echo "$i - Either grabbing failed or $i does not have ssh key on git" echo "$i won't be able to login" - rm $USERPATH/"$i"/.ssh/authorized_keys + rm "$USERPATH"/"$i"/.ssh/authorized_keys fi else @@ -113,7 +132,7 @@ ORGMEMBERS_COMPARE=$(echo -n "`curl -L -s \ -H "Authorization: Bearer $TOKEN" \ -H "X-GitHub-Api-Version: 2022-11-28" \ https://api.github.com/orgs/$ORG/members | jq -r ".[].login"`" \ - | sed 's/\ /|/g' |sed -r 's/^/\(/' |sed -r 's/$/\)/') + | sed 's/\ /|/g' | sed -r 's/^/\(/' | sed -r 's/$/\)/') for i in $LOCALMEMBERS; do From 0d07a6f064f1cc3bfb1104e00108529a12b20ad7 Mon Sep 17 00:00:00 2001 From: Werner Date: Tue, 11 Jun 2024 15:52:17 +0200 Subject: [PATCH 06/13] remove debug --- utils/users_sync.sh | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/utils/users_sync.sh b/utils/users_sync.sh index 7711a104..723790bb 100644 --- a/utils/users_sync.sh +++ b/utils/users_sync.sh @@ -18,7 +18,7 @@ USERPATH=/var/www/users SFTPGROUP=sftponly # classic token from any organization member with "read:org" permission -TOKEN=xxxxxxxxx +TOKEN=xxxxxx # the organization you want to read members from ORG=armbian @@ -55,7 +55,7 @@ then echo "Add this to your \"sshd_config\" if not done already." echo "" echo "Match Group $SFTPGROUP" - echo " ChrootDirectory $PATUSERH/%u" + echo " ChrootDirectory $USERPATH/%u" echo " ForceCommand internal-sftp" echo " AllowTcpForwarding no" echo "" @@ -83,9 +83,6 @@ echo "Already existing members at \"$USERPATH\": \"$LOCALMEMBERS\"." # ...and make it comparable for shell (remove trailing slash, replace newline with | and add round brackets) LOCALMEMBERS_COMPARE=$(echo -n "`ls -d -- */`" | sed 's/\///g' | tr '\n' '|' | sed -r 's/^/\(/' | sed -r 's/$/\)/') -# DEBUG -exit 0 -# END DEBUG # loop through remote org members and add if not existing for i in $ORGMEMBERS; do @@ -93,7 +90,7 @@ for i in $ORGMEMBERS; do if ! [[ $i =~ $LOCALMEMBERS_COMPARE ]]; then # skip locally already existing users # create local user and directory - echo " $i - no local directory found. Creating..." + echo "$i - no local directory found. Creating..." if ! useradd -m -s /bin/bash -G "$SFTPGROUP" -d "$USERPATH"/"$i" "$i" then echo "$i's directory could not be created for whatever reason" From ad3abd822be0e6785a72a11857da7bc1946b17b6 Mon Sep 17 00:00:00 2001 From: Werner Date: Wed, 12 Jun 2024 06:38:15 +0200 Subject: [PATCH 07/13] set shell to false --- utils/users_sync.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/users_sync.sh b/utils/users_sync.sh index 723790bb..fabe54fa 100644 --- a/utils/users_sync.sh +++ b/utils/users_sync.sh @@ -91,7 +91,7 @@ for i in $ORGMEMBERS; do # create local user and directory echo "$i - no local directory found. Creating..." - if ! useradd -m -s /bin/bash -G "$SFTPGROUP" -d "$USERPATH"/"$i" "$i" + if ! useradd -m -s /bin/false -G "$SFTPGROUP" -d "$USERPATH"/"$i" "$i" then echo "$i's directory could not be created for whatever reason" exit 1 From 0e999b0992ab68b4f96dbb26706dcd6fc780ddba Mon Sep 17 00:00:00 2001 From: Werner Date: Wed, 12 Jun 2024 06:45:16 +0200 Subject: [PATCH 08/13] add checks for curl and jq --- utils/users_sync.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/utils/users_sync.sh b/utils/users_sync.sh index fabe54fa..ba5fc106 100644 --- a/utils/users_sync.sh +++ b/utils/users_sync.sh @@ -32,6 +32,12 @@ BLOCKLIST='armbianworker|examplemember1|examplemember2' ### CHECKS +# Check if curl is installed +command -v curl >/dev/null 2>&1 || echo >&2 "\"curl\" not found. Aborting." + +# Check if jq is installed +command -v jq >/dev/null 2>&1 || echo >&2 "\"jq\" not found. Aborting." + # validate token RESPONSE=$(curl -sS -f -I -H "Authorization: token $TOKEN" https://api.github.com | grep -i x-oauth-scopes |grep -c read:org) if [[ $RESPONSE != 1 ]]; then From f5f3fffcb952f0e011651b93c8fd7185a19499da Mon Sep 17 00:00:00 2001 From: Werner Date: Wed, 12 Jun 2024 16:03:35 +0200 Subject: [PATCH 09/13] fix permissions and path --- utils/users_sync.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/utils/users_sync.sh b/utils/users_sync.sh index ba5fc106..6552c8f2 100644 --- a/utils/users_sync.sh +++ b/utils/users_sync.sh @@ -12,13 +12,13 @@ # NO trailing slash! # the owner of the parent directory must be "root"! # configure nginx accordingly -USERPATH=/var/www/users +USERPATH=/armbianusers # which group is used to catch and jail users into their sftp chroot? SFTPGROUP=sftponly # classic token from any organization member with "read:org" permission -TOKEN=xxxxxx +TOKEN=xxx # the organization you want to read members from ORG=armbian @@ -38,6 +38,7 @@ command -v curl >/dev/null 2>&1 || echo >&2 "\"curl\" not found. Aborting." # Check if jq is installed command -v jq >/dev/null 2>&1 || echo >&2 "\"jq\" not found. Aborting." + # validate token RESPONSE=$(curl -sS -f -I -H "Authorization: token $TOKEN" https://api.github.com | grep -i x-oauth-scopes |grep -c read:org) if [[ $RESPONSE != 1 ]]; then @@ -61,7 +62,7 @@ then echo "Add this to your \"sshd_config\" if not done already." echo "" echo "Match Group $SFTPGROUP" - echo " ChrootDirectory $USERPATH/%u" + echo " ChrootDirectory $USERPATH" echo " ForceCommand internal-sftp" echo " AllowTcpForwarding no" echo "" @@ -109,6 +110,7 @@ for i in $ORGMEMBERS; do mkdir -p "$USERPATH"/"$i"/.ssh curl -s https://github.com/"$i".keys > "$USERPATH"/"$i"/.ssh/authorized_keys chown -R "$i":"$SFTPGROUP" "$USERPATH"/"$i"/.ssh + chmod 700 "$USERPATH"/"$i"/.ssh chmod 600 "$USERPATH"/"$i"/.ssh/authorized_keys # Check if grabbed stuff are actual ssh keys. @@ -118,14 +120,15 @@ for i in $ORGMEMBERS; do if [[ $CHECK_KEYS != 0 ]]; then echo "$i - $CHECK_KEYS key/s for $i imported" else - echo "$i - Either grabbing failed or $i does not have ssh key on git" - echo "$i won't be able to login" + echo "(!) $i - Either grabbing failed or $i does not have ssh key on git" + echo "(!) $i won't be able to login" rm "$USERPATH"/"$i"/.ssh/authorized_keys fi else echo "$i - local directory found. Skipping..." # TODO: update ssh keys here + fi done From 5f99e6c30381fa88605b1559d4c994e8a71efadf Mon Sep 17 00:00:00 2001 From: Werner Date: Thu, 13 Jun 2024 13:32:43 +0200 Subject: [PATCH 10/13] fix user deletion, adjust logic --- utils/users_sync.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/utils/users_sync.sh b/utils/users_sync.sh index 6552c8f2..0c9ed7f3 100644 --- a/utils/users_sync.sh +++ b/utils/users_sync.sh @@ -133,19 +133,20 @@ for i in $ORGMEMBERS; do done # remove local users not exsting in remote org -ORGMEMBERS_COMPARE=$(echo -n "`curl -L -s \ +ORGMEMBERS_COMPARE=$(curl -L -s \ -H "Accept: application/vnd.github+json" \ -H "Authorization: Bearer $TOKEN" \ -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/orgs/$ORG/members | jq -r ".[].login"`" \ - | sed 's/\ /|/g' | sed -r 's/^/\(/' | sed -r 's/$/\)/') + https://api.github.com/orgs/$ORG/members | jq -r ".[].login" \ + | grep -v -E -- "$BLOCKLIST" \ + | tr '\n' '|' | sed -r 's/^/\(/' | sed -r 's/\|$/\)/') for i in $LOCALMEMBERS; do - if ! [[ $i =~ $ORGMEMBERS_COMPARE ]]; then # compare local user against list of remote org members. If not found carry on + if [[ $i =~ $ORGMEMBERS_COMPARE ]]; then # compare local user against list of remote org members. If not found carry on + echo "$i is still member of remote org. Skipping..." + else echo "$i is not or no longer in the list of remote org members. Removing its legacy..." userdel --remove "$i" - else - echo "$i is still member of remote org. Skipping..." fi done From d679ecc0ebe95fcc0df58fbf8e79abea068294f7 Mon Sep 17 00:00:00 2001 From: Werner Date: Thu, 13 Jun 2024 16:26:01 +0200 Subject: [PATCH 11/13] functions, key refreshing - put more often used stuff into functions - add key updating --- utils/users_sync.sh | 74 +++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/utils/users_sync.sh b/utils/users_sync.sh index 0c9ed7f3..847c13fe 100644 --- a/utils/users_sync.sh +++ b/utils/users_sync.sh @@ -72,6 +72,31 @@ fi ### END CHECKS +### FUNCTIONS + +grab_keys() { +# $1 = username + echo "Trying to grab ssh keys for $1" + mkdir -p "$USERPATH"/"$1"/.ssh + curl -s https://github.com/"$1".keys > "$USERPATH"/"$1"/.ssh/authorized_keys + chown -R "$1":"$SFTPGROUP" "$USERPATH"/"$1"/.ssh + chmod 700 "$USERPATH"/"$1"/.ssh + chmod 600 "$USERPATH"/"$1"/.ssh/authorized_keys + + # Check if grabbed stuff are actual ssh keys. + # curl response for members w/o keys is "not found" but exit code is still 0 + # so this needs to be worked around + CHECK_KEYS=$(grep -c -E "^ssh" "$USERPATH"/"$1"/.ssh/authorized_keys) + if [[ $CHECK_KEYS != 0 ]]; then + echo "$i - $CHECK_KEYS key/s for $1 imported" + else + echo "(!) $1 - Either grabbing failed or $i does not have ssh key on git" + echo "(!) $1 won't be able to login" + rm "$USERPATH"/"$1"/.ssh/authorized_keys + fi +} + + # grab a list of current remote org members, filter blocked ones echo "Grabbing a list of all current members of \"$ORG\"." echo "Excluded by blocklist are \"$BLOCKLIST\"." @@ -81,6 +106,7 @@ ORGMEMBERS=$(curl -L -s \ -H "X-GitHub-Api-Version: 2022-11-28" \ https://api.github.com/orgs/$ORG/members | jq -r ".[].login" \ | grep -v -E -- "$BLOCKLIST" ) +echo "DEBUG: \$ORGMEMBERS: $ORGMEMBERS" # Grab a list of local directories... # We assume that existing directory means locally existing user as well @@ -89,7 +115,7 @@ LOCALMEMBERS=$(echo -n "`ls -d -- */`" | sed 's/\///g' | tr '\n' ' ') echo "Already existing members at \"$USERPATH\": \"$LOCALMEMBERS\"." # ...and make it comparable for shell (remove trailing slash, replace newline with | and add round brackets) LOCALMEMBERS_COMPARE=$(echo -n "`ls -d -- */`" | sed 's/\///g' | tr '\n' '|' | sed -r 's/^/\(/' | sed -r 's/$/\)/') - +echo "DEBUG: \$LOCALMEMBERS_COMPARE: $LOCALMEMBERS_COMPARE" # loop through remote org members and add if not existing for i in $ORGMEMBERS; do @@ -103,50 +129,34 @@ for i in $ORGMEMBERS; do echo "$i's directory could not be created for whatever reason" exit 1 fi - echo "$i directory created" + echo "$i - user and directory created" # grab ssh keys and put into user's .ssh/authorized_keys file - echo "Trying to grab ssh keys" - mkdir -p "$USERPATH"/"$i"/.ssh - curl -s https://github.com/"$i".keys > "$USERPATH"/"$i"/.ssh/authorized_keys - chown -R "$i":"$SFTPGROUP" "$USERPATH"/"$i"/.ssh - chmod 700 "$USERPATH"/"$i"/.ssh - chmod 600 "$USERPATH"/"$i"/.ssh/authorized_keys - - # Check if grabbed stuff are actual ssh keys. - # curl response for members w/o keys is "not found" but exit code is still 0 - # so this needs to be worked around - CHECK_KEYS=$(grep -c -E "^ssh" "$USERPATH"/"$i"/.ssh/authorized_keys) - if [[ $CHECK_KEYS != 0 ]]; then - echo "$i - $CHECK_KEYS key/s for $i imported" - else - echo "(!) $i - Either grabbing failed or $i does not have ssh key on git" - echo "(!) $i won't be able to login" - rm "$USERPATH"/"$i"/.ssh/authorized_keys - fi + grab_keys $i else - echo "$i - local directory found. Skipping..." - # TODO: update ssh keys here + echo "$i - local directory found. Trying to update keys..." + grab_keys $i fi done -# remove local users not exsting in remote org -ORGMEMBERS_COMPARE=$(curl -L -s \ - -H "Accept: application/vnd.github+json" \ - -H "Authorization: Bearer $TOKEN" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/orgs/$ORG/members | jq -r ".[].login" \ - | grep -v -E -- "$BLOCKLIST" \ - | tr '\n' '|' | sed -r 's/^/\(/' | sed -r 's/\|$/\)/') - +echo "" +echo "Removing no longer existing members" +echo "" +### remove local users not exsting in remote org +# make list of remote organization members comparable +ORGMEMBERS_COMPARE=$(echo $ORGMEMBERS | tr '\n' ' ' | sed 's/\ /\|/g'| sed -r 's/^/\(/' | sed -r 's/\|$/\)/') +echo "DEBUG: \$ORGMEMBERS_COMPARE: $ORGMEMBERS_COMPARE" +echo "DEBUG: \$LOCALMEMBERS: $LOCALMEMBERS" +# loop through org members and compare against local list for i in $LOCALMEMBERS; do if [[ $i =~ $ORGMEMBERS_COMPARE ]]; then # compare local user against list of remote org members. If not found carry on echo "$i is still member of remote org. Skipping..." else - echo "$i is not or no longer in the list of remote org members. Removing its legacy..." + echo "$i is not or no longer in the list of remote org members or has been blocklisted. Removing its legacy..." userdel --remove "$i" fi done + From b0000c8b0aba4032d36b83805bd5489aee41b6e9 Mon Sep 17 00:00:00 2001 From: Werner Date: Fri, 14 Jun 2024 12:56:26 +0200 Subject: [PATCH 12/13] shellcheck --- utils/users_sync.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/users_sync.sh b/utils/users_sync.sh index 847c13fe..a9a6f8c6 100644 --- a/utils/users_sync.sh +++ b/utils/users_sync.sh @@ -132,11 +132,11 @@ for i in $ORGMEMBERS; do echo "$i - user and directory created" # grab ssh keys and put into user's .ssh/authorized_keys file - grab_keys $i + grab_keys "$i" else echo "$i - local directory found. Trying to update keys..." - grab_keys $i + grab_keys "$i" fi done @@ -146,7 +146,7 @@ echo "Removing no longer existing members" echo "" ### remove local users not exsting in remote org # make list of remote organization members comparable -ORGMEMBERS_COMPARE=$(echo $ORGMEMBERS | tr '\n' ' ' | sed 's/\ /\|/g'| sed -r 's/^/\(/' | sed -r 's/\|$/\)/') +ORGMEMBERS_COMPARE=$(echo "$ORGMEMBERS" | tr '\n' ' ' | sed 's/\ /\|/g'| sed -r 's/^/\(/' | sed -r 's/\|$/\)/') echo "DEBUG: \$ORGMEMBERS_COMPARE: $ORGMEMBERS_COMPARE" echo "DEBUG: \$LOCALMEMBERS: $LOCALMEMBERS" # loop through org members and compare against local list From 151d3f26d9af76a6d35b9583e44bb0f6351e6562 Mon Sep 17 00:00:00 2001 From: Werner Date: Sun, 30 Jun 2024 13:24:01 +0200 Subject: [PATCH 13/13] toggle DEBUG and ask for confirmation... ...before user data is being deleted. --- utils/users_sync.sh | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/utils/users_sync.sh b/utils/users_sync.sh index a9a6f8c6..16885a76 100644 --- a/utils/users_sync.sh +++ b/utils/users_sync.sh @@ -25,6 +25,10 @@ ORG=armbian # Users that shall not get access BLOCKLIST='armbianworker|examplemember1|examplemember2' + +# enable debugging +DEBUG=yes + ### END CONFIG @@ -106,7 +110,7 @@ ORGMEMBERS=$(curl -L -s \ -H "X-GitHub-Api-Version: 2022-11-28" \ https://api.github.com/orgs/$ORG/members | jq -r ".[].login" \ | grep -v -E -- "$BLOCKLIST" ) -echo "DEBUG: \$ORGMEMBERS: $ORGMEMBERS" +if [ $DEBUG == "yes" ]; then echo -e "DEBUG: \$ORGMEMBERS:\n$ORGMEMBERS\n\n"; fi # Grab a list of local directories... # We assume that existing directory means locally existing user as well @@ -115,7 +119,7 @@ LOCALMEMBERS=$(echo -n "`ls -d -- */`" | sed 's/\///g' | tr '\n' ' ') echo "Already existing members at \"$USERPATH\": \"$LOCALMEMBERS\"." # ...and make it comparable for shell (remove trailing slash, replace newline with | and add round brackets) LOCALMEMBERS_COMPARE=$(echo -n "`ls -d -- */`" | sed 's/\///g' | tr '\n' '|' | sed -r 's/^/\(/' | sed -r 's/$/\)/') -echo "DEBUG: \$LOCALMEMBERS_COMPARE: $LOCALMEMBERS_COMPARE" +if [ $DEBUG == "yes" ]; then echo -e "DEBUG: \$LOCALMEMBERS_COMPARE:\n$LOCALMEMBERS_COMPARE\n\n"; fi # loop through remote org members and add if not existing for i in $ORGMEMBERS; do @@ -142,21 +146,28 @@ for i in $ORGMEMBERS; do done echo "" -echo "Removing no longer existing members" +echo "Removing no longer existing members of \"$ORG\"" echo "" ### remove local users not exsting in remote org # make list of remote organization members comparable ORGMEMBERS_COMPARE=$(echo "$ORGMEMBERS" | tr '\n' ' ' | sed 's/\ /\|/g'| sed -r 's/^/\(/' | sed -r 's/\|$/\)/') -echo "DEBUG: \$ORGMEMBERS_COMPARE: $ORGMEMBERS_COMPARE" -echo "DEBUG: \$LOCALMEMBERS: $LOCALMEMBERS" +if [ $DEBUG == "yes" ]; then echo -e "\nDEBUG: \$ORGMEMBERS_COMPARE:\n$ORGMEMBERS_COMPARE\n\n"; fi +if [ $DEBUG == "yes" ]; then echo -e "\nDEBUG: \$LOCALMEMBERS:\n$LOCALMEMBERS\n\n"; fi # loop through org members and compare against local list for i in $LOCALMEMBERS; do if [[ $i =~ $ORGMEMBERS_COMPARE ]]; then # compare local user against list of remote org members. If not found carry on - echo "$i is still member of remote org. Skipping..." + echo "$i is still member of \"$ORG\". Skipping..." else - echo "$i is not or no longer in the list of remote org members or has been blocklisted. Removing its legacy..." - userdel --remove "$i" + echo -e "$i is not or no longer in the list of \"$ORG\" members or has been blocklisted.\nRemove the user and their files? (y/N)\nTHIS CANNOT BE UNDONE!\n" + read -n 1 INPUT + : "${INPUT:=n}" + if [ $INPUT == "y" ]; then + userdel --remove "$i" + else + echo "Keeping $i" + fi fi done +