質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
VPN

VPN(Virtual Private Network)は、仮想プライベートネットワークとも呼ばれ、インターネットに接続してるユーザー間に仮想的な通信トンネルを構築した組織内ネットワークです。認証や暗号化を用いて通信経路を保護し安全なネットワークの構築ができます。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

736閲覧

簡易的なVPNの実装について

退会済みユーザー

退会済みユーザー

総合スコア0

VPN

VPN(Virtual Private Network)は、仮想プライベートネットワークとも呼ばれ、インターネットに接続してるユーザー間に仮想的な通信トンネルを構築した組織内ネットワークです。認証や暗号化を用いて通信経路を保護し安全なネットワークの構築ができます。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2023/03/10 08:09

簡易的なVPNの実装について

現在、セキュリティの学習を行う学生です。
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 Network 2import Foundation 3import SwiftSocket 4 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) in 13 // カプセル化するための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 = XXXXXXXX 22       //ここでパケットを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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2023/03/10 08:24

その VPN は、例えば Safari や他のアプリの通信を VPN 経由にするってことでしょうか?
退会済みユーザー

退会済みユーザー

2023/03/10 09:51

@hoshi-takanori 様 その様な認識です。VPNサーバを経由した通信にする形になります。
退会済みユーザー

退会済みユーザー

2023/03/10 09:53

@poto568 情報提供頂きありがとうございます。 拝読いたしました。wireguard内のソースコードを読んでみようと思います。
guest

回答1

0

ベストアンサー

私だったら、

  1. openVPNを使って実装
  2. openVPNのプロトコルについて学習
  3. openVPNと同じAPIでフルスクラッチで部分的にVPNクライアント実装

などとすると思います。
また、2・3の段階でさらにいろいろ引っかかると思います
VPNだとTCPではなくUDPを用いることが多いとか...

学習のためでも、既存のライブラリを使用して実装したのち、それを置き換えるものをスクラッチとした方が悩むことが少ないかと思います

投稿2023/03/13 10:28

k5kkkkk

総合スコア102

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2023/03/16 10:58

ご回答いただきありがとうございます。 既存ライブラリからの学習を行なった後に、置き換えるよう実装を行いたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問