/
Olegghg
/
project
Обзор
Документация
Войти
/
Olegghg
/
project
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
server/server.py
156 строк
6 KB
Olegghg
d
12 дек 2024, 18:17
12 дек 2024, 18:17
8e49050
Код
Авторство
О чём код?
import os import sys import logging import socket import base64 import fcntl, struct, subprocess, errno import hashlib from dnslib import DNSRecord, QTYPE, RR, A, TXT from Crypto.Cipher import AES logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, format='%(asctime)s %(levelname)s %(message)s') SERVER_PASSWORD_HASH = os.environ.get("VPN_SERVER_PASSWORD_HASH", "").strip() raw_key = os.environ.get("VPN_SESSION_KEY", "default_secret").encode('utf-8') SESSION_KEY = hashlib.sha256(raw_key).digest() logging.debug(f"Server SESSION_KEY (SHA256): {SESSION_KEY.hex()}") TUN_DEVICE = "/dev/net/tun" TUNSETIFF = 0x400454ca IFF_TUN = 0x0001 IFF_NO_PI = 0x1000 tun = open(TUN_DEVICE, 'rb+', buffering=0) ifr = struct.pack('16sH', b'tun0', IFF_TUN | IFF_NO_PI) fcntl.ioctl(tun, TUNSETIFF, ifr) # Настройка TUN-интерфейса subprocess.run(["ip", "addr", "flush", "dev", "tun0"], check=False) subprocess.run(["ip", "link", "set", "tun0", "up"], check=True) subprocess.run(["ip", "addr", "add", "10.9.0.1/24", "dev", "tun0"], check=True) authenticated_clients = set() def setup_routing(): """Настройка маршрутизации и NAT на сервере.""" # Включаем форвардинг пакетов subprocess.run(["sysctl", "-w", "net.ipv4.ip_forward=1"], check=True) # Настраиваем NAT для VPN-трафика subprocess.run(["iptables", "-t", "nat", "-A", "POSTROUTING", "-s", "10.9.0.0/24", "-o", "eth0", "-j", "MASQUERADE"], check=True) logging.info("Server routing and NAT configured successfully") def encrypt_data(data, key): cipher = AES.new(key, AES.MODE_GCM) ciphertext, tag = cipher.encrypt_and_digest(data) logging.debug(f"Server encrypt_data: nonce={cipher.nonce.hex()}, ciphertext={ciphertext.hex()[:50]}..., tag={tag.hex()}") return cipher.nonce + ciphertext + tag def decrypt_data(data, key): nonce = data[:16] tag = data[-16:] ciphertext = data[16:-16] logging.debug(f"Server decrypt_data: nonce={nonce.hex()}, ciphertext={ciphertext.hex()[:50]}..., tag={tag.hex()}") cipher = AES.new(key, AES.MODE_GCM, nonce=nonce) return cipher.decrypt_and_verify(ciphertext, tag) def read_tun_packet(): try: packet = tun.read(65535) logging.debug(f"Server read_tun_packet: {packet.hex()[:50]}... (length={len(packet)})") return packet except OSError as e: if e.errno != errno.EAGAIN: logging.error("Server error reading from tun: %s", e) return None def write_tun_packet(packet): logging.debug(f"Server write_tun_packet: {packet.hex()[:50]}... (length={len(packet)})") tun.write(packet) def handle_auth(qname, request, addr): """Обработка аутентификации клиента.""" parts = qname.split('.') if len(parts) >= 4 and parts[-3] == "auth" and parts[-2] == "example" and parts[-1] == "com": hash_part1 = parts[0] hash_part2 = parts[1] full_hash_hex = hash_part1 + hash_part2 logging.debug(f"Server handle_auth: received={full_hash_hex}, expected={SERVER_PASSWORD_HASH}") if full_hash_hex == SERVER_PASSWORD_HASH: authenticated_clients.add(addr[0]) logging.info(f"Client {addr[0]} authenticated successfully") reply = request.reply() reply.add_answer(RR("auth.example.com.", QTYPE.A, rdata=A("127.0.0.1"))) return reply.pack() return request.reply().pack() def handle_vpn_payload(qname, request, addr): """Обработка VPN-запросов.""" parts = qname.split('.') base32_parts = parts[:-3] enc_b32 = ''.join(base32_parts) enc_b32 = enc_b32.upper() missing_padding = (8 - len(enc_b32) % 8) % 8 enc_b32_padded = enc_b32 + '=' * missing_padding logging.debug(f"Server handle_vpn_payload: base32_data={enc_b32_padded}") enc_data = base64.b32decode(enc_b32_padded) try: packet = decrypt_data(enc_data, SESSION_KEY) write_tun_packet(packet) response_packet = read_tun_packet() txt_data = "" if response_packet: enc_response = encrypt_data(response_packet, SESSION_KEY) enc_b32_resp = base64.b32encode(enc_response).decode('utf-8').rstrip('=') txt_data = enc_b32_resp reply = request.reply() reply.add_answer(RR(qname, QTYPE.A, rdata=A("127.0.0.1"))) reply.add_answer(RR(qname, QTYPE.TXT, rdata=TXT(txt_data))) return reply.pack() except Exception as e: logging.error(f"Server Error decrypting VPN payload: {e}") reply = request.reply() reply.add_answer(RR(qname, QTYPE.A, rdata=A("127.0.0.1"))) reply.add_answer(RR(qname, QTYPE.TXT, rdata=TXT(""))) return reply.pack() def main(): setup_routing() sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind(("0.0.0.0", 53)) logging.info("Starting DNS server on 0.0.0.0:53") while True: data, addr = sock.recvfrom(4096) try: request = DNSRecord.parse(data) qname = str(request.q.qname).strip('.') qtype = QTYPE[request.q.qtype] if qtype == "TXT" and "auth.example.com" in qname: response = handle_auth(qname, request, addr) if response: sock.sendto(response, addr) continue if addr[0] not in authenticated_clients: logging.warning(f"Server client {addr[0]} not authenticated yet") sock.sendto(request.reply().pack(), addr) continue if qname.endswith("vpn.example.com"): response = handle_vpn_payload(qname, request, addr) if response: sock.sendto(response, addr) else: logging.debug(f"Server received non-VPN query: {qname}") reply = request.reply() reply.add_answer(RR(qname, QTYPE.A, rdata=A("8.8.8.8"))) sock.sendto(reply.pack(), addr) except Exception as e: logging.error(f"Server error processing request from {addr}: {e}") if __name__ == "__main__": main()