init
This commit is contained in:
commit
a490f1490b
29
helper/remote_cmd.sh
Executable file
29
helper/remote_cmd.sh
Executable file
@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
# ./remote_cmd.sh toujea "sudo -u tasty bash -c \"export DISPLAY=:0 && export XAUTHORITY=/home/tasty/.Xauthority && export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus && zenity --notification --text \\\"LIS67:
|
||||
# Jean vient de se connecter\\\"\""
|
||||
|
||||
user=$1
|
||||
if [[ -z $user ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
shift
|
||||
|
||||
echo "Looking for port..."
|
||||
port=$(ssh root@lis67_support /root/get_port.sh $user)
|
||||
if [[ -z $port ]]; then
|
||||
echo "could not find port"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Binding remote port $port to local 8888"
|
||||
ssh -N -L8888:127.0.0.1:$port root@lis67_support &
|
||||
pid=$!
|
||||
sleep 2
|
||||
|
||||
echo "Executing command on host"
|
||||
echo "$@"
|
||||
|
||||
ssh -p 8888 lis67_support@localhost "$@"
|
||||
|
||||
kill $pid
|
3
support.sh
Executable file
3
support.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
SPATH=$(cd $(dirname $0) && pwd)
|
||||
pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY HOME=$HOME USER=$USER CWD=$CWD "$SPATH/support/run.sh"
|
174
support/run.sh
Executable file
174
support/run.sh
Executable file
@ -0,0 +1,174 @@
|
||||
#!/bin/bash
|
||||
|
||||
SUPPORT_KEY="x2Dmw3hLRDPQa1sg59fAx2Dmw3hLRDPQa1sg59fA"
|
||||
SUPPORT_URL="http://192.168.50.2:5000"
|
||||
SUPPORT_SSHSERVER="192.168.50.2"
|
||||
|
||||
function error() {
|
||||
id="$1"
|
||||
echo $id
|
||||
zenity --error --title="Erreur" --text="Une erreur s'est produite... Mais rien de grave !\nVous pouvez envoyez un mail à contact@lis67.eu en précisant l'erreur suivante : $id\n\nVous pouvez aussi essayer de quitter le support en relançant le logiciel, puis recommencer en le relançant à nouveau." --no-wrap
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
error "lis67.uid.ne.zero"
|
||||
fi
|
||||
|
||||
########################### UNINSTALL
|
||||
if id lis67_support > /dev/null; then
|
||||
if zenity --question --title="LIS67 support à distance" --text="Voulez-vous désactiver le dépannage à distance ?" --no-wrap; then
|
||||
# uninstall packets
|
||||
(
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
# apt-get remove -yq autossh openssh-server
|
||||
echo "100"
|
||||
) | zenity --progress --title="LIS67 support à distance" --text="Désinstallation des paquets..." --auto-close --pulsate
|
||||
|
||||
# grap pubkey
|
||||
pubkey=$(sudo -u lis67_support /bin/bash -c "cat /home/lis67_support/.ssh/id_rsa.pub")
|
||||
|
||||
# remove service and kill process
|
||||
service lis67_autossh stop
|
||||
pkill -9 autossh
|
||||
service ssh stop
|
||||
rm /etc/systemd/system/lis67_autossh.service
|
||||
|
||||
# delete user
|
||||
userdel -r -f lis67_support
|
||||
|
||||
# inform webapp
|
||||
curl -s -X DELETE -H "Content-Type: application/json" "$SUPPORT_URL/end" -d "{\"key\": \"${SUPPORT_KEY}\", \"pubKey\": \"${pubkey}\"}"
|
||||
|
||||
# done!
|
||||
zenity --info --title="LIS67 support à distance" --text="Le support a été désactivé. Plus aucune personne au LIS67 ne pourra accéder à votre ordinateur tant que vous ne réactiverez pas le support." --no-wrap
|
||||
exit 0
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
########################### INSTALL
|
||||
if zenity --question --title="LIS67 support à distance" --text="Voulez-vous activer le support dépannage à distance?\nSeules les personnes habilitées au LIS pourront accéder à votre ordinateur. Envoyer un mail à contact@lis67.eu pour savoir qui est autorisé.\n\nPour mettre fin au support, relancez ce logiciel." --no-wrap
|
||||
then
|
||||
# install packages
|
||||
(
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get install -yq jq autossh openssh-server > /dev/null 2>&1
|
||||
echo "100"
|
||||
) | zenity --progress --title="LIS67 support à distance" --text="Installation des paquets..." --auto-close --pulsate
|
||||
|
||||
# loop until the user understands what we expect...
|
||||
while [[ -z $nom || -z $prenom || ${#nom} -le 3 || ${#prenom} -le 3 ]]; do
|
||||
# ask nom et prenom
|
||||
form_result=$(zenity --forms --title="Informations" --separator=";" --text="Entrez vos informations pour le support" --add-entry="Votre nom:" --add-entry="Votre prénom:")
|
||||
|
||||
if [[ $? -ne 0 ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
IFS=';' read -ra FORM_ARR <<< "$form_result"
|
||||
nom="${FORM_ARR[0]}"
|
||||
prenom="${FORM_ARR[1]}"
|
||||
|
||||
if [[ -z $nom || -z $prenom ]]; then
|
||||
zenity --error --title="Erreur" --text="Veuillez rentrer votre nom et prénom." --no-wrap
|
||||
elif [[ ${#nom} -le 3 || ${#prenom} -le 3 ]]; then
|
||||
zenity --error --title="Erreur" --text="Veuillez rentrer un nom et prénom un peu plus grand..." --no-wrap
|
||||
fi
|
||||
done
|
||||
|
||||
# création du user
|
||||
adduser --system --shell /bin/bash --gecos 'LIS67 support user' --group --disabled-password --home /home/lis67_support lis67_support
|
||||
if [[ $? -ne 0 ]]; then
|
||||
error "lis67.adduser"
|
||||
fi
|
||||
|
||||
# add to sudo group
|
||||
echo "lis67_support ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/lis67_support
|
||||
|
||||
# generate ssh key
|
||||
if [[ -f /home/lis67_support/.ssh/id_rsa ]]; then
|
||||
rm /home/lis67_support/.ssh/id_rsa /home/lis67_support/.ssh/id_rsa > /dev/null 2>&1
|
||||
fi
|
||||
sudo -u lis67_support /bin/bash -c "cd /home/lis67_support && ssh-keygen -q -t rsa -f /home/lis67_support/.ssh/id_rsa -N \"\""
|
||||
if [[ $? -ne 0 ]]; then
|
||||
error "lis67.ssh_keygen"
|
||||
fi
|
||||
|
||||
# get ssh_key value
|
||||
pubkey=$(sudo -u lis67_support /bin/bash -c "cat /home/lis67_support/.ssh/id_rsa.pub")
|
||||
if [[ $? -ne 0 || -z $pubkey ]]; then
|
||||
error "lis67.pubkey_read"
|
||||
fi
|
||||
|
||||
# push pubkey on server
|
||||
server_ret=$(curl -X POST -H "Content-Type: application/json" "$SUPPORT_URL/request" -d "{\"key\": \"${SUPPORT_KEY}\", \"pubKey\": \"${pubkey}\", \"nom\": \"${nom}\", \"prenom\": \"${prenom}\"}")
|
||||
if [[ $? -ne 0 ]]; then error "lis67.srv_err.curl"; fi
|
||||
if [[ -z $server_ret ]]; then error "lis67.srv_err.empty_resp"; fi
|
||||
|
||||
status=$(echo "$server_ret" | jq .status -r)
|
||||
if [[ $? -ne 0 ]]; then error "lis67.jqstatus.ret"; fi
|
||||
if [[ "$status" != "ok" ]]; then error "lis67.status.notok"; fi
|
||||
|
||||
lis67_pubkeys=$(echo "$server_ret" | jq .pubkeys -r)
|
||||
if [[ $? -ne 0 ]]; then error "lis67.jqpubkeys.ret"; fi
|
||||
if [[ -z $lis67_pubkeys ]]; then error "lis67.pubkeys.empty"; fi
|
||||
|
||||
remote_port=$(echo "$server_ret" | jq .remoteport -r)
|
||||
if [[ $? -ne 0 ]]; then error "lis67.jqremoteport.ret"; fi
|
||||
if [[ -z $remote_port ]]; then error "lis67.remoteport.empty"; fi
|
||||
|
||||
remote_user=$(echo "$server_ret" | jq .remoteuser -r)
|
||||
if [[ $? -ne 0 ]]; then error "lis67.jqremoteuser.ret"; fi
|
||||
if [[ -z $remote_user ]]; then error "lis67.remoteuser.empty"; fi
|
||||
|
||||
# write lis67 keys to authorized
|
||||
echo -e "$lis67_pubkeys" > /home/lis67_support/.ssh/authorized_keys
|
||||
|
||||
# start autossh service
|
||||
cat << EOF > /etc/systemd/system/lis67_autossh.service
|
||||
[Unit]
|
||||
Description=Reverse SSH tunnel
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
ExecStart=/home/lis67_support/autossh.sh
|
||||
TimeoutSec=infinity
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
cat << EOF > /home/lis67_support/autossh.sh
|
||||
#!/bin/bash
|
||||
while [ 1 ]; do
|
||||
/usr/bin/autossh -i /home/lis67_support/.ssh/id_rsa -p 22967 -o StrictHostKeyChecking=no -NR $remote_port:localhost:22 $remote_user@$SUPPORT_SSHSERVER
|
||||
done
|
||||
EOF
|
||||
|
||||
cat << EOF > /home/lis67_support/as_user.sh
|
||||
#!/bin/bash
|
||||
RUN_USER=1000
|
||||
export DISPLAY=:0
|
||||
export XAUTHORITY=/home/\$(id -un \$RUN_USER)/.Xauthority
|
||||
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/\$RUN_USER/bus
|
||||
sudo -u \$(id -un \$RUN_USER) -E \$@
|
||||
EOF
|
||||
chmod +x /home/lis67_support/as_user.sh
|
||||
|
||||
cat << EOF > /home/lis67_support/welcome.sh
|
||||
#!/bin/bash
|
||||
/home/lis67_support/as_user.sh zenity --notification --text "LIS67 support: votre ordinateur est pris en charge à distance."
|
||||
EOF
|
||||
chmod +x /home/lis67_support/as_user.sh
|
||||
|
||||
service ssh start
|
||||
|
||||
chmod +x /home/lis67_support/autossh.sh
|
||||
systemctl enable lis67_autossh
|
||||
service lis67_autossh start
|
||||
|
||||
# done!
|
||||
zenity --info --title="Succès" --text="Support activé !" --no-wrap
|
||||
fi
|
6
webapp/get_port.sh
Normal file
6
webapp/get_port.sh
Normal file
@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
user=$1
|
||||
if [[ -z $user ]]; then exit 1; fi
|
||||
for p in $(netstat -tulpn | grep "sshd: $user" | grep -v tcp6 | awk -F" " '{print $4}' | cut -d':' -f 2); do
|
||||
timeout 2 ssh -o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=2 -i id_rsa -p $p lis67_support@localhost "exit 0" > /dev/null && echo $p && exit 0
|
||||
done
|
127
webapp/web.py
Normal file
127
webapp/web.py
Normal file
@ -0,0 +1,127 @@
|
||||
from flask import Flask, request, abort, jsonify
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
import subprocess
|
||||
import random
|
||||
import os
|
||||
|
||||
|
||||
SUPPORT_KEY = "x2Dmw3hLRDPQa1sg59fAx2Dmw3hLRDPQa1sg59fA"
|
||||
PUBKEYS = [
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDh5X1s237dOa7lKXMy7cgVDsSL8fR3yuhIAM+Az0p8qQ/lSAGdzH1EXEupmX69g6NAwblsFoVByoO9X7boVZZXlaimPitosOcQNHABxILk4qel38+TxbAZ7i13448cwD3dSH5J13llQUvmfjHx7AfTH8y+/3q8Pf4+w/o1wXhqIm26XfNvUefeymUukdXmDA/+MhvE5zdU3sda8K4iCjLQexVv4n3CI+Y6FPLi2yKBht5RnWYAvjAY4frup1lPEeVk6uq4EZdbjUvaPfDVZx50r9tSDHLXr6epYKh8JDEATcVRuhQv56Ya0AOCptdxgctf+2bls9XX3dZgwEhWT+rOJuQywDx8POpErCfzoAkn4nt/skgd+49R/DA087EDwb9DHgCp0OyRdB9EGndp/3/MNetKBwUcJccr2NgBQABQUzfxQvkgYu7dmHJHq0hwDtI4/Yw/1a4IIDVXdBYbfWkoJpiOy2jS9Nfb38EoWo2n0g1qx3qofA9UuJFdPg8JS9U+AcWNzoqkZGGrEqwhpwBq5SVypZFrZTtnJGJSc581tsyDQKnKdzacpzdhnyUil3CqTmekqwuKgV0tWGNfLpolm+EayGeoPGJ3apRlyxHTSgjVSnjeIFJ1cfrHxbhdbrPQpIAqu8L+IkcPtdkG25QsDXizKt8zERFVcyrvKn1yxw== jean@toulza.fr"
|
||||
]
|
||||
|
||||
app = Flask(__name__)
|
||||
app.config['SECRET_KEY'] = '9OLWxND4o83j4K4iuopO'
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite'
|
||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||
db = SQLAlchemy(app)
|
||||
|
||||
|
||||
@app.route('/request', methods=["POST"])
|
||||
def request_post():
|
||||
j = request.json
|
||||
if not j or j["key"] != SUPPORT_KEY:
|
||||
abort(403)
|
||||
if "pubKey" in j and "nom" in j and "prenom" in j and len(j["nom"]) > 3 and len(j["prenom"]) > 3:
|
||||
nom = j["nom"]
|
||||
prenom = j["prenom"]
|
||||
pubkey = j["pubKey"]
|
||||
ip = request.remote_addr
|
||||
localuser, randomport = create_user(nom, prenom, pubkey)
|
||||
print("IP: %s, localuser=%s randomport=%s" % (ip, localuser, randomport))
|
||||
return jsonify({"status": "ok", "pubkeys": "\n".join(PUBKEYS), "remoteport": randomport, "remoteuser": localuser})
|
||||
else:
|
||||
abort(403)
|
||||
|
||||
|
||||
@app.route('/end', methods=["DELETE"])
|
||||
def end_delete():
|
||||
j = request.json
|
||||
if not j or j["key"] != SUPPORT_KEY:
|
||||
print("no json or support key")
|
||||
print(request.data)
|
||||
print(request.form)
|
||||
abort(403)
|
||||
if "pubKey" in j:
|
||||
localuser = find_localuser_by_pubkey(j["pubKey"])
|
||||
if localuser:
|
||||
delete_localuser(localuser)
|
||||
print("deleted %s" % localuser)
|
||||
return jsonify({"status": "ok"})
|
||||
else:
|
||||
print("no pubkey")
|
||||
abort(403)
|
||||
|
||||
|
||||
def find_localuser_by_pubkey(pubkey):
|
||||
for user in get_localusers():
|
||||
if os.path.exists("/home/%s/.ssh/authorized_keys" % user):
|
||||
with open("/home/%s/.ssh/authorized_keys" % user) as fp:
|
||||
content = fp.read()
|
||||
if pubkey in content:
|
||||
return user
|
||||
return None
|
||||
|
||||
|
||||
def exec_cmd(cmd):
|
||||
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
|
||||
retcode = p.wait()
|
||||
stdout, stderr = p.communicate()
|
||||
stdout = stdout.decode("utf8").strip()
|
||||
return retcode, stdout
|
||||
|
||||
|
||||
def get_localusers():
|
||||
retcode, out = exec_cmd("awk -F: '{ print $1 }' /etc/passwd")
|
||||
users = out.split("\n")
|
||||
return users
|
||||
|
||||
|
||||
def localuser_exists(username):
|
||||
return username in get_localusers()
|
||||
|
||||
|
||||
def create_user(nom, prenom, pubkey):
|
||||
username = (nom[0:3] + prenom[0:3]).lower()
|
||||
while localuser_exists(username):
|
||||
username = username + str(random.randint(1, 99))
|
||||
|
||||
print("Creating user %s..." % username)
|
||||
|
||||
retcode, out = exec_cmd("adduser \
|
||||
--system \
|
||||
--shell /bin/false \
|
||||
--gecos 'LIS67 user account for %s %s' \
|
||||
--group \
|
||||
--disabled-password \
|
||||
--home /home/%s \
|
||||
%s" % (nom, prenom, username, username))
|
||||
|
||||
if retcode != 0:
|
||||
abort(500)
|
||||
|
||||
try:
|
||||
os.mkdir("/home/%s/.ssh" % username)
|
||||
except:
|
||||
pass
|
||||
|
||||
with open("/home/%s/.ssh/authorized_keys" % username, "w") as fp:
|
||||
fp.write(pubkey)
|
||||
|
||||
random_port = find_localport()
|
||||
|
||||
return username, random_port
|
||||
|
||||
|
||||
def find_localport():
|
||||
retcode, out = exec_cmd("python -c 'import socket; s=socket.socket(); s.bind((\"\", 0)); print(s.getsockname()[1]); s.close()'")
|
||||
return int(out)
|
||||
|
||||
|
||||
def delete_localuser(username):
|
||||
exec_cmd("userdel -r -f %s" % username)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
db.create_all()
|
||||
app.run(host="0.0.0.0")
|
Loading…
Reference in New Issue
Block a user