Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

vpngen.py 9.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. import json
  2. import os
  3. import os.path
  4. import re
  5. import shutil
  6. from subprocess import call
  7. class VpnGenError:
  8. Success = 0,
  9. VpnAlreadyExists = 1,
  10. VpnDoesNotExists = 2,
  11. ClientAlreadyExists = 3,
  12. ClientDoesNotExists = 4
  13. class VpnGen:
  14. default_config_base_dir = ""
  15. default_config_file = ""
  16. default_client_config_file = ""
  17. ovpn_config_path = ""
  18. def __init__(self, default_config_path, ovpn_config_path):
  19. self.default_config_base_dir = os.path.abspath(default_config_path)
  20. self.default_config_file = "%s.conf" % self.default_config_base_dir
  21. self.default_client_config_file = "%s%sclients%sclient.conf" % (self.default_config_base_dir, os.sep, os.sep)
  22. self.ovpn_config_path = os.path.abspath(ovpn_config_path)
  23. def f7(self, seq):
  24. seen = set()
  25. seen_add = seen.add
  26. return [x for x in seq if not (x in seen or seen_add(x))]
  27. def get_vpn_vars(self):
  28. with open(self.default_config_file, "r") as f:
  29. default_config = f.read()
  30. variables = re.findall('\$\{([^}]+)}', default_config)
  31. variables += ["KEY_COUNTRY", "KEY_PROVINCE", "KEY_CITY", "KEY_ORG", "KEY_EMAIL"]
  32. variables = self.f7(variables)
  33. return variables
  34. def get_client_vars(self, vpn_name):
  35. default_client_config_path = self.get_client_default_config_path(vpn_name)
  36. if not os.path.exists(default_client_config_path):
  37. return None
  38. with open(default_client_config_path, "r") as f:
  39. default_config = f.read()
  40. variables = re.findall('\$\{([^}]+)}', default_config)
  41. variables = self.f7(variables)
  42. return variables
  43. def get_base_dir(self, vpn_name):
  44. return "%s%s%s%s" % (self.ovpn_config_path, os.sep, vpn_name, os.sep)
  45. def get_config_path(self, vpn_name):
  46. return "%s%s%s.conf" % (self.ovpn_config_path, os.sep, vpn_name)
  47. def get_vpn_variables_path(self, vpn_name):
  48. base_dir = self.get_base_dir(vpn_name)
  49. return "%svpngen.json" % base_dir
  50. def get_easy_rsa_dir(self, vpn_name):
  51. base_dir = self.get_base_dir(vpn_name)
  52. return "%seasy-rsa%s" % (base_dir, os.sep)
  53. def get_easy_rsa_key_dir(self, vpn_name):
  54. easyrsadir = self.get_easy_rsa_dir(vpn_name)
  55. return "%skeys%s" % (easyrsadir, os.sep)
  56. def get_pkitool_path(self, vpn_name):
  57. easyrsadir = self.get_easy_rsa_dir(vpn_name)
  58. return "%spkitool" % easyrsadir
  59. def get_client_default_config_path(self, vpn_name):
  60. base_dir = self.get_base_dir(vpn_name)
  61. return "%s%sclients/client.conf" % (base_dir, os.sep)
  62. def get_client_dir(self, vpn_name, client_name):
  63. base_dir = self.get_base_dir(vpn_name)
  64. return "%sclients%s%s-%s%s" % (base_dir, os.sep, client_name, vpn_name, os.sep)
  65. def get_client_config_path(self, vpn_name, client_name):
  66. client_dir = self.get_client_dir(vpn_name, client_name)
  67. return "%s%s-%s.conf" % (client_dir, client_name, vpn_name)
  68. def get_client_generated_files_paths(self, vpn_name, client_name):
  69. keys_dir = self.get_easy_rsa_key_dir(vpn_name,)
  70. return [
  71. "%s%s.crt" % (keys_dir, client_name),
  72. "%s%s.key" % (keys_dir, client_name)
  73. ]
  74. def get_client_tarball_path(self, vpn_name, client_name):
  75. base_dir = self.get_base_dir(vpn_name)
  76. return "%sclients%s%s-%s.tar.bz2" % (base_dir, os.sep, client_name, vpn_name)
  77. def get_server_needed_files_paths(self, vpn_name):
  78. keys_dir = self.get_easy_rsa_key_dir(vpn_name)
  79. return [
  80. "%sca.crt" % keys_dir,
  81. "%sta.key" % keys_dir
  82. ]
  83. def get_all_needed_files_paths(self, vpn_name, client_name):
  84. return self.get_client_generated_files_paths(vpn_name, client_name) +\
  85. self.get_server_needed_files_paths(vpn_name)
  86. def setup_vars(self, vpn_name, variables):
  87. easyrsadir = self.get_easy_rsa_dir(vpn_name)
  88. os.environ["KEY_COUNTRY"] = variables['KEY_COUNTRY']
  89. os.environ["KEY_PROVINCE"] = variables['KEY_PROVINCE']
  90. os.environ["KEY_CITY"] = variables['KEY_CITY']
  91. os.environ["KEY_ORG"] = variables['KEY_ORG']
  92. os.environ["KEY_OU"] = variables['KEY_ORG']
  93. os.environ["KEY_CN"] = variables['KEY_ORG']
  94. os.environ["KEY_NAME"] = variables['KEY_ORG']
  95. os.environ["KEY_EMAIL"] = variables['KEY_EMAIL']
  96. os.environ["KEY_SIZE"] = variables['KEY_SIZE']
  97. os.environ["CA_EXPIRE"] = variables['CA_EXPIRE']
  98. os.environ["KEY_EXPIRE"] = variables['KEY_EXPIRE']
  99. os.environ["EASY_RSA"] = easyrsadir
  100. os.environ["OPENSSL"] = "openssl"
  101. os.environ["PKCS11TOOL"] = "pkcs11-tool"
  102. os.environ["GREP"] = "grep"
  103. os.environ["KEY_CONFIG"] = "%s%s" % (easyrsadir, "openssl.cnf")
  104. os.environ["KEY_DIR"] = "%s%s" % (easyrsadir, "keys")
  105. os.environ["PKCS11_MODULE_PATH"] = "dummy"
  106. os.environ["PKCS11_PIN"] = "dummy"
  107. def create_vpn(self, vpn_name, variables):
  108. base_dir = self.get_base_dir(vpn_name)
  109. conf_file = self.get_config_path(vpn_name)
  110. conf_vpngen_file = self.get_vpn_variables_path(vpn_name)
  111. if os.path.exists(base_dir) or os.path.exists(conf_file):
  112. return VpnGenError.VpnAlreadyExists
  113. with open(self.default_config_file, "r") as f:
  114. default_config = f.read()
  115. variables['name'] = vpn_name
  116. for variable in variables:
  117. default_config = default_config.replace("${%s}" % variable, variables[variable])
  118. os.makedirs(base_dir)
  119. with open(conf_file, "w") as f:
  120. f.write(default_config)
  121. os.rmdir(base_dir)
  122. shutil.copytree(self.default_config_base_dir, base_dir)
  123. curdir = os.curdir
  124. easyrsadir = self.get_easy_rsa_dir(vpn_name)
  125. pkitool = self.get_pkitool_path(vpn_name)
  126. os.chdir(easyrsadir)
  127. self.setup_vars(vpn_name, variables)
  128. call([".%sclean-all" % os.sep])
  129. call([pkitool, "--initca"])
  130. call([pkitool, "server"])
  131. call([".%sbuild-dh" % os.sep])
  132. call(["openssl", "ca", "-gencrl",
  133. "-keyfile", "keys%sca.key" % os.sep,
  134. "-cert", "keys%sca.crt" % os.sep,
  135. "-out", "keys%crl.pem" % os.sep,
  136. "-config", "openssl.cnf"])
  137. call(["openvpn", "--genkey", "--secret", "keys%sta.key" % os.sep])
  138. with open(conf_vpngen_file, "w") as f:
  139. json.dump({'variables': variables}, f, indent=4, separators=(',', ': '))
  140. os.chdir(curdir)
  141. return VpnGenError.Success
  142. def remove_vpn(self, vpn_name):
  143. base_dir = self.get_base_dir(vpn_name)
  144. conf_file = self.get_config_path(vpn_name)
  145. if not os.path.exists(base_dir) and not os.path.exists(conf_file):
  146. return VpnGenError.VpnDoesNotExists
  147. os.remove(conf_file)
  148. shutil.rmtree(base_dir)
  149. return VpnGenError.Success
  150. def create_client(self, vpn_name, client_name, variables):
  151. base_dir = self.get_base_dir(vpn_name)
  152. client_conf_file = self.get_client_config_path(vpn_name, client_name)
  153. if not os.path.exists(base_dir):
  154. return VpnGenError.VpnDoesNotExists
  155. client_dir = self.get_client_dir(vpn_name, client_name)
  156. if os.path.exists(client_dir):
  157. return VpnGenError.ClientAlreadyExists
  158. curdir = os.curdir
  159. easyrsadir = self.get_easy_rsa_dir(vpn_name)
  160. pkitool = self.get_pkitool_path(vpn_name)
  161. os.chdir(easyrsadir)
  162. self.setup_vars(vpn_name, variables)
  163. os.environ["KEY_CN"] = client_name
  164. os.environ["KEY_NAME"] = client_name
  165. call([pkitool, client_name])
  166. os.chdir(curdir)
  167. self.build_client(vpn_name, client_name, variables)
  168. return VpnGenError.Success
  169. def remove_client(self, vpn_name, client_name):
  170. base_dir = self.get_base_dir(vpn_name)
  171. if not os.path.exists(base_dir):
  172. return VpnGenError.VpnDoesNotExists
  173. client_dir = self.get_client_dir(vpn_name, client_name)
  174. if not os.path.exists(client_dir):
  175. return VpnGenError.ClientDoesNotExists
  176. return VpnGenError.Success
  177. def rebuild_clients(self, vpn_name):
  178. base_dir = self.get_base_dir(vpn_name)
  179. return VpnGenError.Success
  180. def build_client(self, vpn_name, client_name, variables):
  181. client_dir = self.get_client_dir(vpn_name, client_name)
  182. client_conf_file = self.get_client_config_path(vpn_name, client_name)
  183. client_default_config_path = self.get_client_default_config_path(vpn_name)
  184. with open(client_default_config_path, "r") as f:
  185. client_default_config = f.read()
  186. variables['name'] = vpn_name
  187. variables['client'] = client_name
  188. for variable in variables:
  189. client_default_config = client_default_config.replace("${%s}" % variable, variables[variable])
  190. os.makedirs(client_dir)
  191. with open(client_conf_file, "w") as f:
  192. f.write(client_default_config)
  193. files_paths = self.get_all_needed_files_paths(vpn_name, client_name)
  194. for file_path in files_paths:
  195. split = os.path.splitext(file_path)
  196. dest = "%s%s-%s%s" % (client_dir, os.path.basename(split[0]), vpn_name, split[1])
  197. shutil.copy(file_path, dest)
  198. files_names = list(map(lambda file_path: os.path.basename(file_path), files_paths))
  199. call(["tar", "cfj", self.get_client_tarball_path(vpn_name, client_name),
  200. "-C", self.get_easy_rsa_key_dir(vpn_name)] + files_names)