|
@@ -4,6 +4,8 @@ import os
|
|
|
import sys
|
|
|
import smtplib
|
|
|
import subprocess
|
|
|
+import textwrap
|
|
|
+import tempfile
|
|
|
from email.mime.multipart import MIMEMultipart
|
|
|
from email.mime.text import MIMEText
|
|
|
|
|
@@ -22,42 +24,42 @@ def check_env (member_id):
|
|
|
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:
|
|
|
+ if member_id < 2 or member_id > 253:
|
|
|
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\
|
|
|
+ s'arrête à 253.")
|
|
|
+ print("Si on a plus de 253 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 ():
|
|
|
+def gen_wg_keys (temp_dir):
|
|
|
"""
|
|
|
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)
|
|
|
+ pubkey_path = os.path.join(temp_dir, "pub.key")
|
|
|
+ privkey_path = os.path.join(temp_dir, "priv.key")
|
|
|
+ psk_path = os.path.join(temp_dir, "psk.key")
|
|
|
+ subprocess.run(\
|
|
|
+ "wg genkey | tee %s | wg pubkey > %s" % (privkey_path, pubkey_path),\
|
|
|
+ shell=True, check=True)
|
|
|
+ subprocess.run("wg genpsk > %s" % (psk_path), shell=True, check=True)
|
|
|
+ return (privkey_path, pubkey_path, psk_path)
|
|
|
|
|
|
-def update_wg_config (member_id, config_file, pubkey, pshkey):
|
|
|
+def update_wg_config (member_id, config_file, pubkey_path, psk_path):
|
|
|
"""
|
|
|
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)
|
|
|
+ PublicKey = %PUBKEY%
|
|
|
+ PresharedKey = %PSK%
|
|
|
+ AllowedIPs = 10.0.0.{1}/24, fd00::{1}/64
|
|
|
+ '''.format(member_id)
|
|
|
with open(config_file, "a") as wg_file:
|
|
|
wg_file.write(wg_config)
|
|
|
+ subprocess.run('sed -i "s/%PUBKEY%/$(cat %s)/" "%s"' % (pubkey_path, config_file), shell=True, check=True)
|
|
|
+ subprocess.run('sed -i "s/%PSK%/$(cat %s)/" "%s"' % (psk_path, config_file), shell=True, check=True)
|
|
|
|
|
|
class Email:
|
|
|
"""
|
|
@@ -74,7 +76,7 @@ class Email:
|
|
|
self.to_addr = to_addr
|
|
|
self.server = server
|
|
|
|
|
|
-def send_mail(email, wgconfig):
|
|
|
+def send_mail(email, wgconfig_path):
|
|
|
"""
|
|
|
Send the private key by email.
|
|
|
|
|
@@ -89,13 +91,19 @@ def send_mail(email, wgconfig):
|
|
|
password = email.passwd
|
|
|
msg = MIMEMultipart()
|
|
|
msg['Subject'] = "Votre acces VPN Baionet"
|
|
|
+ msg['Date'] = formatdate(localtime=True)
|
|
|
msg['From'] = email.from_addr
|
|
|
msg['To'] = [email.to_addr]
|
|
|
- body = '''
|
|
|
+ body = textwrap.dedent('''
|
|
|
blahblah, cf le wiki blahblahblah
|
|
|
- '''
|
|
|
- mail_static_text = random.choice(messages)
|
|
|
+ ''')
|
|
|
msg.attach([MIMEText(body), MIMEText(config)])
|
|
|
+ with open(wgconfig_path, "rb") as f:
|
|
|
+ part = MIMEApplication(
|
|
|
+ f.read(),
|
|
|
+ Name=os.path.basename(f))
|
|
|
+ part['Content-Disposition'] = 'attachment; filename=%s' % basename(f)
|
|
|
+ msg.attach(part)
|
|
|
username = email.username
|
|
|
server = smtplib.SMTP(email.server)
|
|
|
server.ehlo()
|
|
@@ -111,42 +119,49 @@ def send_mail(email, wgconfig):
|
|
|
# 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.")
|
|
|
+ print("ERREUR: Le numéro d'adhérant est en théorie un entier entre 1 et 253.")
|
|
|
+ sys.exit(1)
|
|
|
try:
|
|
|
+ service_name = os.environ['SYSTEMD_SERVICE']
|
|
|
+ wg_config_dir = os.environ['WG_CONF_PATH']
|
|
|
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")
|
|
|
+ with tempfile.TemporaryDirectory() as temp_dir:
|
|
|
+ (privkey_path, pubkey_path, psk_path) = gen_wg_keys(temp_dir)
|
|
|
+ print("[+] Modification de la configuration wireguard")
|
|
|
+ try:
|
|
|
+ update_wg_config(member_id, config_file, pubkey_path, psk_path)
|
|
|
+ except Exception as e:
|
|
|
+ print("ERREUR: Problème lors de la génération des clés wireguard.")
|
|
|
+ print(e)
|
|
|
+ sys.exit(1)
|
|
|
+ print("[+] Chargement de la nouvelle interface réseau")
|
|
|
+ try:
|
|
|
+ os.system("systemctl restart %s" % (service_name))
|
|
|
+ except Exception as e:
|
|
|
+ print("ERREUR: Problème lors du redémarrage du service.")
|
|
|
+ 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']
|
|
|
+ server = os.environ['SYSTEMD_SERVICE']
|
|
|
+ server = os.environ['SYSTEMD_SERVICE']
|
|
|
+ email = Email(username, passwd, "bureau@baionet.fr", member_email, server)
|
|
|
+ send_email(email, privkey_path)
|
|
|
+ except Exception as e:
|
|
|
+ print("ERREUR: erreur lors de l'envoi de l'email.")
|
|
|
+ print("Veuillez envoyer tout ce message d'erreur à la liste de diffusion technique")
|
|
|
+ print(e)
|
|
|
+ sys.exit(1)
|
|
|
+ print("[+] Nettoyage")
|
|
|
+ print("[+] DONE")
|