Bonjour,
Je vous écrit car je perd un peu pieds dans ce que je fais.
Pour mettre en situation :
J'ai deux machines : C (Chief) et W (Worker).
C et W sont connectée entre elles par un tunnel OpenVpn, W étant le client OpenVpn.
L'interface OpenVpn de C est fixe et connue.
Prenons par exemple "10.8.0.10".
L'interface OpenVpn de W est variable, mais est récupérable via un "ifconfig" (en regardant l'interface "tun0").
Prenons par exemple "10.8.1.140".
Je ne vais travailler que sur W, W étant une machine sous Debian 8.
Sur W, je doit soit attendre une communication de C (création d'un serveur de socket sur W), soit communiquer avec C (création d'une socket simple sur W).
J'ai lu ce sujet, dans lequel on précise qu'une connexion TCP est identifié par un set de 5 valeurs : {<protocol>, <src addr>, <src port>, <dest addr>, <dest port>}
Pour le serveur de socket, il suffit de décider arbitrairement d'un port que W va écouter (1004 par exemple) et sur lequel C va se connecter.
Je pense savoir ce que je fais mais j'aimerais avoir confirmation :
Dans un premiers temps, on créer la socket, la binder, puis listen. Cela permettra de mettre les 3 premières valeur de mon set aux bonnes valeurs.
La gestion des erreurs est faites, mais a volontairement été supprimé pour raccourcir le code.
Ensuite, lors d'une connexion sur le port 1004 de l'interfaces 10.8.1.140 (soit l'interface OpenVpn, ce que je veux), je vais regarder qui se connecte et décider si oui ou non je l'ajoute.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 void vpnServer_InitializeSocket(vpnserver_s *self) { struct sockaddr_in sin; self->sock = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0); memset(&sin, 0, sizeof(sin)); sin.sin_addr.s_addr = inet_addr("10.8.1.140"); sin.sin_port = htons(1004); sin.sin_family = AF_INET; bind(self->sock, (struct sockaddr *)&sin, sizeof(sin); listen(self->sock, self->nbMaxClient); self->max = self->sock; }
Donc la normalement, on est d'accord que mon serveur de socket ne peut accepter que des connexion qui passe au travers de mon vpn ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 bool CpvpnServer_AddClient(cpvpnserver_s *self) { int sock = -1; struct sockaddr_in incomming = {0}; socklen_t incommingLen = sizeof(incomming); char incommingIp[INET6_ADDRSTRLEN]; /* As-t-on la place d'ajouter un client ? */ if (self->nbClient >= self->nbMaxClient) { return ; } /* On récupère la socket */ sock = accept(self->sock, (struct sockaddr *)&incomming, &incommingLen); /* on regarde qui se connecte */ inet_ntop(incomming.sin_family, &incomming.sin_addr, incommingIp, INET6_ADDRSTRLEN); if (strcmp(incommingIp, "10.8.0.10") != 0) { return ; } /* Mise à jour de la structure */ self->max = sock > self->max ? sock : self->max; self->clients[self->nbClient] = sock; ++self->nbClient; }
Ensuite, et c'est la que je patauge, c'est lorsque je veux connecter W sur un port spécifique de C à travers OpenVpn.
Mettons que le port soit le 1098.
Idem, la gestion des erreurs est faites, mais a volontairement été supprimé pour raccourcir le code.
Ce qui me gêne ici, c'est que je vois pas pourquoi ma socket serait obligé de passer par l'interface OpenVpn. Il "suffirait" que le tunnel OpenVpn soit down et qu'une machine attaquante soit connecter avec le port 1098 et avec l'interfaces "10.8.0.10" disponible pour que je me connecte comme une fleur sur ce dernier, ce que je ne désire évidemment pas.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 int SocketToOpenVpn(int port) { struct sockaddr_in serv_addr; int sock = -1; sock = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(port); inet_pton(AF_INET, "10.8.0.10", &serv_addr.sin_addr); connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr); return (sock); }
j'ai pensé à ajouter bind avec le connect comme je l'avais fait avec le serveur de socket, mais étrangement, même si le code fonctionne (il y a bien une connexion et un envoie de donnée), je n'arrive pas a retrouver ces données sur C.
Est-ce la bonne piste ?
Ai-je une erreur de raisonnement, compréhension dans ce que je fais ?
Merci de votre lecture.
Cordialement.
Partager