123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- #!/usr/bin/env python3
- import os
- import sys
- import smtplib
- import subprocess
- from email.mime.multipart import MIMEMultipart
- from email.mime.text import MIMEText
- def check_env (member_id):
- """
- Checks if wireguard is correctly installed, the script is run as
- root and the member id is correct.
- """
- wgInstalled = os.system("wg")
- if os.geteuid() != 0:
- print("On a besoin des droits root pour créer un accès VPN.")
- print("Relancez la commande préfixée d'un sudo.")
- raise Exception("Got root?")
- if wgInstalled != 0:
- print("Wireguard ne semble pas être installé sur votre système.")
- print("Il faudrait installer wireguard-tools et wireguard-dkms avant\
- d'utiliser ce script")
- raise Exception("Install wg")
- if member_id == 0 and member_id < 255:
- print("On est parti du principe que les IDs des membres commencent à 1.")
- print("Ah, aussi, pour le moment, on est aussi partis du principe que ça \
- s'arrête à 254.")
- print("Si on a plus de 254 membres, premièrement, FÉLICITATIONS venant\
- du Félix du passé. Par contre, il faut repenser l'adressage des \
- IPs du VPN maintenant :( Ranson du succès j'immagine.")
- raise Exception("Wrong member_id")
- def gen_wg_keys ():
- """
- Generates both the private and the public wireguard key of the new member.
- """
- priv = subprocess.run(["wg","genkey"], stdout=subprocess.STDOUT).decode(encoding='UTF-8').rstrip()
- psk = subprocess.run(["wg","genpsk"], stdout=subprocess.STDOUT).decode(encoding='UTF-8').rstrip()
- pub = subprocess.run(["bash", "-c", "echo EMrXWE+Qw4i0+sAgoNHVECgR+e1nWmEF3qYU4ftWUG8= | wg pubkey"]\
- , stdout=subprocess.PIPE).decode(encoding='UTF-8').rstrip()
- # TODO: better error check.
- if os.system(gen_key_cmd) != 0:
- print("Erreur lors de la génération des clés wireguard.")
- print("Contactez un administrateur technique en lui envoyant le message d'erreur ci-dessus.")
- sys.exit(1)
- return (priv, psk, pub)
- def update_wg_config (member_id, config_file, pubkey, pshkey):
- """
- Generate the wireguard configuration for this new member.
- """
- wg_new_peer = '''
- [Peer]
- PublicKey = {0}
- PresharedKey = {1}
- AllowedIPs = 10.0.0.{2}/24, fd00::{2}/64
- '''.format(pubkey, pshkey, member_id)
- with open(config_file, "a") as wg_file:
- wg_file.write(wg_config)
- class Email:
- """
- Not really necessary, but I keep on forgetting most of an email arguments
- and I'm tired of debugging this class of error... Too bad we don't have any
- record type in this language.
- PS: I hate python.
- """
- def __init__(self, username, passwd, from_addr, to_addr, server):
- self.username = username
- self.passwd = passwd
- self.from_addr = from_addr
- self.to_addr = to_addr
- self.server = server
- def send_mail(email, wgconfig):
- """
- Send the private key by email.
- email:
- - username
- - passwd
- - from_addr
- - to_addr
- - server
- """
- from_addr = 'bureau@baionet.fr'
- password = email.passwd
- msg = MIMEMultipart()
- msg['Subject'] = "Votre acces VPN Baionet"
- msg['From'] = email.from_addr
- msg['To'] = [email.to_addr]
- body = '''
- blahblah, cf le wiki blahblahblah
- '''
- mail_static_text = random.choice(messages)
- msg.attach([MIMEText(body), MIMEText(config)])
- username = email.username
- server = smtplib.SMTP(email.server)
- server.ehlo()
- server.starttls()
- server.login(email.username, email.passwd)
- server.sendmail(email.from_addr, email.to_addr, msg.as_string())
- server.quit()
- # Main Function
- # =============
- # *************
- # =============
- # 1- Parse email/member id.
- # 2- Génère les clés wireguard.
- # 3- Crée/déploie la configuration wireguard.
- # 4- Crée/déploie la nouvelle interface réseau.
- # 5- Envoie la clé à l'utilisateur (email/manuellement)
- if __name__ == '__main__':
- key_dir = "/etc/wireguard/keys"
- wg_config_dir = "/etc/wireguard"
- if_config_dir = "/etc/interfaces"
- # On récupère le numéro d'adhérant et l'email d'un nouveau membre.
- member_email = input("EMail du nouveau membre: ")
- try:
- member_id = int(input("Numéro d'adhérant du nouveau membre: "))
- except Exception as e:
- print("ERREUR: Le numéro d'adhérant est en théorie un entier entre 1 et 254.")
- try:
- check_env(member_id)
- except Exception as e:
- print("ERREUR: problème d'environnement: {}".format(e))
- sys.exit(1)
- print("[+] Génération des clés wireguard")
- (privkey_path,pubkey_path) = gen_wg_keys(member_id, tmp_key_dir)
- print("[+] Création de la configuration wireguard")
- create_wg_config(member_id, wg_config_dir, privkey_path, pubkey_path)
- print("[+] Création de la nouvelle interface réseau")
- create_if_file(member_id, if_config_dir)
- print("[+] Chargement de la nouvelle interface réseau")
- os.system("systemctl restart networking")
- print("[+] Envoi de la clé privée au nouveau membre")
- try:
- username = os.environ['SMTP_USERNAME']
- passwd = os.environ['SMTP_PASSWD']
- server = os.environ['SMTP_SERVER']
- email = Email(username, passwd, "bureau@baionet.fr", member_email, "smtp://server")
- send_email(email, privkey_path, "")
- except Exception as e:
- print("ERREUR: erreur lors de l'envoi de l'email: {}".format(e))
- print("Veuillez envoyer tout ce message d'erreur à la liste bayonetek@framalistes.org")
- sys.exit(1)
- print("[+] Nettoyage")
- print("[+] DONE")
|