Ich versuche, ein Netzwerk für ein benutzerdefiniertes VPN zu konfigurierenKLIENTBibliothek.
Was ich nicht herausfinden kann
Ich muss den Datenverkehr in einem normalen VPN-Setup weiterleiten können, damit mein C++-Skript den Tunnel lesen/schreiben kann. Wenn ich mich nicht irre, sollte das Setup ungefähr so aussehen:
Normal Setup How I think my setup should be
------------------------------------------------------------
Start → Aplication → Finish Start → Aplication → Finish
↓ ↑ ↓ ↑
iface-enp0s3 iface-enp0s3
↓ ↑ ↓ ↑
interwebs iface-tun1
↓ ↑
c++ script
↓ ↑
vpn-server
↓ ↑
interwebs
Ich weiß, dass mein C++-Skript dies derzeit nicht tut, es liest derzeit nur Daten vom tun1
Adapter. Das ist vorerst alles, was ich erreichen möchte. Allerdings kriege ich die Routen scheinbar nicht richtig zum Laufen.
Wenn ich besuchehttp://google.comVon meinem Clientsystem aus möchte ich diese Pakete im C++-Skript angezeigt sehen und der Datenverkehr soll nirgendwo anders hingehen.
Sobald ich den gesamten Verkehr richtig umleiten kannohne Hafendass die Verbindung zum VPN über das C++-Skript unter Verwendung der Tunnelschnittstelle hergestellt wurde, werde ich beginnen, es über die VPN-Clientbibliothek zu senden.
Soweit ich weiß, funktioniert das C++-Skript derzeit. Wenn ich 10.0.0.2 (den tun1
Adapter) anpinge, kann ich sehen, dass die Pakete durchkommen.
Ich habe verschiedene Dinge ausprobiert, nämlich Folgendes:
sudo iptables -t nat -A POSTROUTING --out-interface tun1 -j MASQUERADE
sudo iptables -A FORWARD --in-interface enp0s3 -j ACCEPT
Das hat nicht funktioniert.
Hinweis: Ich habe bereits sichergestellt, dass es
net.ipv4.ip_forward
auf eingestellt ist1
, und ich habe ausgeführtsudo sysctl -p
.
Informationen zur aktuellen Konfiguration finden Sie weiter unten.
Hinweis: Ich verwende Ubuntu 16.04 Desktop.
Meine aktuellen Adapter
Hinweis: enp0s3 ist mein primärer Adapter. Dieser läuft auf einer virtuellen Maschine. enp0s3 ist meine Verbindung zum Internet.
enp0s3 Link encap:Ethernet HWaddr 08:00:27:ea:97:d2 inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0 inet6 addr: fe80::8ec8:60b7:f404:77c5/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:58668 errors:0 dropped:0 overruns:0 frame:0 TX packets:39067 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:39002535 (39.0 MB) TX bytes:7442839 (7.4 MB) tun1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 inet addr:10.0.0.1 P-t-P:10.0.0.2 Mask:255.255.255.255 inet6 addr: fe80::fed9:4107:8688:8501/64 Scope:Link UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:16 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:500 RX bytes:0 (0.0 B) TX bytes:984 (984.0 B)
So richte ich meinen tun1
Adapter ein
$ sudo ip tuntap add dev tun1 mode tun
$ sudo ifconfig tun1 10.0.0.1 dstaddr 10.0.0.2 up
Das C++-Skript, das ich höretun1
// Includes ommited.
using namespace std;
typedef void data_receiver(char* data, int length);
struct receive_handle {
data_receiver* receiver;
} typedef receive_handle;
// Function used to retrieve the interface.
static int if_nametofd(char *name)
{
int interface = open("/dev/net/tun", O_RDWR | O_NONBLOCK);
ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
if (ioctl(interface, TUNSETIFF, &ifr)) {
perror("Cannot get TUN interface");
exit(1);
}
return interface;
}
// Called when a packet is received from the tun0 interface.
void received_data(char* data, int length)
{
// Truncate the packet so that we only see the first 15 bytes.
// This way we don't spam the console.
for(int i=0; i<15; ++i)
std::cout << std::hex << (int)data[i];
std::cout << endl;
}
int main()
{
cout << "Getting interface..." << endl;
int iface = if_nametofd("tun1");
cout << "Using interface: " << iface << endl;
cout << "Creating handler..." << endl;
receive_handle* handle = (receive_handle*)malloc(sizeof(receive_handle));
handle->receiver = received_data;
char packet[1024];
cout << "Listening..." << endl;
while (true)
{
if (read(iface, packet, sizeof(packet)) > 0) {
handle->receiver(packet, sizeof(packet));
}
}
return 0;
}
Der einzige Zweck dieses Skripts besteht darin, sich an den Adapter anzuheften tun1
und kontinuierlich von ihm zu lesen.
Antwort1
Sie müssen das Standard-Gateway Ihrer Arbeitsstation ändern. Wenn Sie den folgenden Befehl eingeben, wird das Standard-Gateway Ihres Systems angezeigt.
ip route show table main
default via 1.2.3.4 dev wanif
Sie können es ändern, indem Sie „ip route replace“ (man ip-route) verwenden.
Besser noch, Sie können den Open-VPN-Trick verwenden, um die Standardroute zu überschreiben, ohne sie löschen zu müssen (--redirect-gateway def1).
Dies funktioniert durch das Hinzufügen von zwei Routen, die den gesamten IPv4-Adressraum abdecken. Da jede dieser beiden Routen spezifischer ist als die Standardroute, wird die Standardroute praktisch überschrieben.
Dies geschieht wie folgt:
ip route add 0.0.0.0/1 via 10.0.2.15 dev tun1
ip route add 128.0.0.0/1 via 10.0.2.15 dev tun1
wobei 10.0.2.15 Ihr lokaler Tunnelendpunkt ist.
Da Ihr Skript eine Verbindung „über das normale Internet“ herstellen muss, um einen sinnvollen Tunneldienst bereitzustellen, müssen Sie Ihren Remote-Endpunkt folgendermaßen hinzufügen, um nicht unter die obige Regel zu fallen:
ip route add 7.8.9.10/32 via 1.2.3.4 dev wanif
wobei 7.8.9.10 Ihr Remote-Endpunkt und 1.2.3.4 Ihr ISP-Standard-Gateway ist.
Denken Sie an die Grundregeln der Routing-Regeln: Die spezifischsten haben Vorrang vor den weniger spezifischen