現在、セキュリティの学習を行う学生です。
VPNについての新方式を考える上で、簡易的なVPNを実装したいと考えています。
機能としては以下の通りです。
- スマホアプリ(クライアント)からVPNサーバへの通信を始める
- VPNサーバはクライアントを認証を行う。
- その後、クライアントは、Webサイト閲覧などの通信を暗号化しVPNサーバに転送
- VPNサーバは受信パケットを復号して、該当するサーバ(例: Googleのサイト)に転送
- Webサイトからの返答があれば、VPNサーバが受け取ったのちに暗号化し、クライアントに転送
- クライアントは受け取ったパケットを復号し、返答を受け取る
実装にあたり以下を想定しています。
- 認証方式: ID/パスワード認証
- 暗号化: AES-256-GCM
- クライアントではswiftを用いてiPhoneアプリを作成する
- VPNサーバは処理速度は遅いものの実装難度を考慮しPythonで作成
- OpenVPNなど、既存のVPNライブラリを用いず実装したい
ご教授いただきたいこと
クライアント・VPNサーバ共にコーディング時利用するもの
実装の際にはソケット通信を用いることは分かるのですが、実際の通信パケットをどのように操作するのかがいまいち理解できてません。
考えているのは、パケットキャプチャをして、キャプチャしたパケットに暗号化等の処理をVPNサーバに送るといった処理です。
これを実現するために、どのような処理を行うべきか教えて頂きたいです。また考え方が間違っていましたら、そこもご指摘頂けますと幸いです。
認証等はまだ未実装ですが、ソケット通信部分の大枠のコードを添付致します。
具体的にはクライアント側21行目の処理やサーバ側26行目の処理をお教え頂きたいです。
拙い文章で申し訳ありませんが、ご教授頂けますと幸いです。
該当のソースコード
クライアント側
swift
1import Network2import Foundation3import SwiftSocket4 5let VPN_SERVER_ADDRESS = "VPNサーバのアドレス"6let VPN_SERVER_PORT = "ポート番号"7 8// パケットキャプチャを開始する9let capture = NWPacketCapture.create(interface: .wifi)!10capture.setFilter("tcp")11 12capture.start(queue: .main) { (packet: Data, interface: NWInterface, direction: NWDirection) in13 // カプセル化するためのIPヘッダを作成14 let ipHeader = IPHeader(sourceIP: interface.ipv4Addresses.first!,15 destinationIP: VPN_SERVER_ADDRESS)16 17 // カプセル化するためのTCPヘッダを作成18 let tcpHeader = TCPHeader(destinationPort: VPN_SERVER_PORT)19 20 // ペイロードを作成 ここの処理がわからない。packet.dropFirst()を用いる?21 let payload = XXXXXXXX22 //ここでパケットをAESで暗号化する23 24 25 // カプセル化するためのパケットを作成26 let vpnPacket = ipHeader.data + tcpHeader.data + payload 27 28 // VPNサーバにパケットを送信する29 sendToVPNServer(vpnPacket)30}31 32 33func sendToVPNServer(_ packet: Data) {34 // IPv4ソケットを作成35 let socket = try! RawSocket(protocolFamily: .inet, socketType: .raw, protocol: .ip)36 37 // VPNサーバのアドレスとポートを設定38 let address = InternetAddress(hostname: VPN_SERVER_ADDRESS, port: VPN_SERVER_PORT)39 40 // パケットを送信41 do {42 try socket.write(from: packet, to: address)43 } catch let error {44 print("Failed to send packet: \(error.localizedDescription)")45 }46 47 // ソケットを閉じる48 socket.close()49}
VPNサーバ側
Python
1import socket 2import struct 3 4VPN_SERVER_ADDRESS = "VPNサーバのアドレス"5VPN_SERVER_PORT = ポート番号 6 7# IPv4ソケットを作成8sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_IP)9 10# ソケットオプションを設定して、すべてのパケットを受信するようにする11sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)12sock.bind((VPN_SERVER_ADDRESS, VPN_SERVER_PORT))13 14while True:15 # パケットを受信16 packet, address = sock.recvfrom(65535)17 18 # IPヘッダ、TCPヘッダ、ペイロードを解析19 # ペイロードはAESで復号20 ip_header = packet[:20]21 tcp_header = packet[20:40]22 payload = packet[40:]23 24 # 復号後のパケットのIPヘッダをもとに転送したい25 # IPヘッダから送信先IPアドレスを取得 ここがわからない26 destination_ip = XXXXXXXX 27 28 # パケットを宛先アドレスに転送29 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:30 s.connect(destination_address)31 s.sendall(packet)32
0 コメント