Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

OpenVPN, pf, routage ...

6 réponses
Avatar
Etienne
Bonjour à tous,

J'ai un problème de "plomberie". Je teste pour la première fois OpenVPN,
et ce sur un routeur OpenBSD (5.1) placé entre mon réseau local et mon
FAI. Tant que je fait passer à travers le tunnel _tout_ le traffic
réseau qui va vers ou vient de <ailleurs>, tout va bien. Je remplace
le nom de mon interface habituelle part "tun0" dans ma config pf, et
tout se passe comme avant. Là où ça coince, c'est quand j'essaie de
faire en sorte que pf redirige une certaine partie du traffic vers le
tunnel et laisse le reste passer par le trajet non-chiffré habituel.

Initialement, mon pf.conf est comme ça:

ext_if = "sis0"
int_if = "sis1"

int_lan = "192.168.42.0/24"

set skip on lo
set block-policy return
match in all scrub (no-df)

match out on $ext_if inet from $int_lan to any nat-to ($ext_if)

antispoof quick for $int_if

pass # to establish keep-state

block in on $ext_if from any

Ensuite, j'ai modifié la configuration par défaut d'OpenVPN pour
l'empêcher de faire de la route vers le VPN la route par défaut.

De plus, j'ai rajouté à pf.conf les macros:

vpn_if = "tun0"
machineA = "192.168.42.1"

et les règles:

match in on $int_if inet from $machineA to !$int_lan nat-to ($vpn_if)
pass in on $int_if inet from $machineA to !$int_lan route-to $vpn_if

Enfin, j'ai modifié le resolv.conf de machineA pour lui indiquer le DNS
situé de l'autre côté du tunnel chiffré.

Mais ça ne fonctionne pas, ou seulement de façon chaotique. Par exemple,
machineA ne pas surfer sur le web (je teste avec lynx), ni utiliser
telnet vers un serveur quelconque. Et quand je teste la résolution des
noms avec "host", la réponse met plusieurs secondes à me parvenir.
Pourtant, sur le routeur, elle est quasi-instantanée.

D'autre part, quand j'utilise OpenVPN dans son mode verbeux qui affiche
un caractère lors de chaque operation read/write, je constate que le
déchiffrage est simultané avec la réponse sur machineA.

Enfin, quand je sniffe le traffic sur $ext_if de mon routeur, je vois
plein de paquets ICMP "port unreachable" et quelques TCP "RST,ACK" qui
sortent _en clair_ sur cette interface, avec l'adresse source de $vpn_if.

Je n'y comprends plus rien ?!?! Qu'est-ce que j'ai loupé ?

Merci d'avoir lu jusque-là.

--
Étienne

6 réponses

Avatar
Manuel Giraud
Etienne writes:

match in on $int_if inet from $machineA to !$int_lan nat-to ($vpn_if)
pass in on $int_if inet from $machineA to !$int_lan route-to $vpn_if




Je suis loin d'être un expert en pf mais j'ai un VPN du pauvre au dess us
d'un tunnel ssh avec des règles similaires aux tiennes par contre moi
j'ai un 'rdr-to' en lieu et place de ton 'route-to'. Sinon il y a
toujours 'man pf.conf' mais c'est vrai que ça peut occuper les longues
soirées d'hiver.

--
Manuel Giraud
Avatar
Etienne
Ce bavard de Manuel Giraud vient de nous dire:

match in on $int_if inet from $machineA to !$int_lan nat-to ($vpn_if)
pass in on $int_if inet from $machineA to !$int_lan route-to $vpn_if



Je suis loin d'être un expert en pf mais j'ai un VPN du pauvre au dessus
d'un tunnel ssh avec des règles similaires aux tiennes par contre moi
j'ai un 'rdr-to' en lieu et place de ton 'route-to'.



J'ai remplacé les deux règles ci-dessus par:

match in log on $int_if inet from $machineA to !$int_lan rdr-to ($vpn_if)

Et en fait, c'est pire. :-) Plus rien ne passe de $machineA vers
l'extérieur. Celà dit, ça m'a donné l'idée de remplacer tout par juste:

match in log on $int_if inet from $machineA to !$int_lan nat-to ($vpn_if)

Et là, ça ne marche pas mieux, mais ça me fait disparaître les paquets
ICMP foireux du traffic sur $ext_if. C'est déjà ça.

Je sens que le problème vient du fait que j'applique "nat-to" à l'entrée
("match in) d'une interface, et pas à la sortie. Mais je ne peux pas le
faire sur la sortie de $ext_if: Aucun paquet ne se verrait appliquer cette
règle, puisque la table de routage a déjà redirigé les paquets à
destination du vpn vers $vpn_if.

Une autre idée ?

Sinon il y a toujours 'man pf.conf' mais c'est vrai que ça peut occuper
les longues soirées d'hiver.



Ben comment dire ... C'est pas faute de l'avoir lue, mais rien que pour
comprendre la syntaxe de "route-to", c'est pas la page de manuel qui m'a
aidé (je ne sais pas interprêter le chapitre GRAMMAR, c'est vrai). Et du
reste, la plupart des exemples que j'ai trouvé ici et là suivent la
syntaxe pre-4.7 ...

--
Étienne
Avatar
Manuel Giraud
Etienne writes:

Une autre idée ?



Euh non pas vraiment. Et en regardant de plus près ton problème e st
différent du mien: moi je route tout par le vpn et les règles de mon pf
sont juste là pour accéder correctement à certains port de l a machine
qui sert de relais. Donc voilà ce que j'ai:

$ ifconfig em0
em0: flagsˆ43<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
lladdr 00:24:e8:47:9a:46
priority: 0
groups: phy
media: Ethernet autoselect (1000baseT full-duplex,rxpause,txpause)
status: active
inet6 fe80::224:e8ff:fe47:9f46%em0 prefixlen 64 scopeid 0x1
inet 172.16.13.9 netmask 0xffffff00 broadcast 172.16.13.255

$ ifconfig tun0
tun0: flagsQ<UP,POINTOPOINT,RUNNING> mtu 1500
priority: 0
groups: tun vpn egress
status: active
inet 10.1.1.1 --> 10.1.1.2 netmask 0xfffffffc

$ netstat -rnf inet
Routing tables

Internet:
Destination Gateway Flags Refs Use Mtu Prio Ifa ce
default 10.1.1.1 UGS 7 829 - 8 tun 0
10.1.1.2 10.1.1.1 UH 0 177 - 4 tun 0
173.194.66.100 172.16.13.1 UGHS 3 1969 - L 8 em0
127/8 127.0.0.1 UGRS 0 0 33196 8 lo0
127.0.0.1 127.0.0.1 UH 2 220 33196 4 lo0
172.16.13/24 link#1 UC 1 0 - 4 em0
172.16.13.1 e8:e7:38:14:db:7e UHLc 2 0 - 4 em0
172.16.13.9 127.0.0.1 UGHS 0 0 33196 8 lo0
224/4 127.0.0.1 URS 0 0 33196 8 lo0

Et finalement mon pf.conf:
set skip on lo

relais = "173.194.66.100"
tport = "{www, https}"
uport = "{domain}"

match out proto tcp from phy to $relais port $tport
rdr-to vpn:peer
pass out quick proto tcp from phy to vpn:peer port $tport
nat-to vpn

match out proto udp from phy to $relais port $uport
rdr-to vpn:peer
pass out quick proto udp from phy to vpn:peer port $uport
nat-to vpn

match out on phy from vpn:network nat-to (phy)

pass # to establish keep-state

Voilà (je sais pas si ça peut aider en fait.)
--
Manuel Giraud
Avatar
Etienne
Ce bavard de Manuel Giraud vient de nous dire:

Une autre idée ?



Euh non pas vraiment. Et en regardant de plus près ton problème est
différent du mien: moi je route tout par le vpn et les règles de mon pf
sont juste là pour accéder correctement à certains port de la machine
qui sert de relais. Donc voilà ce que j'ai:



[...]

$ ifconfig tun0
tun0: flagsQ<UP,POINTOPOINT,RUNNING> mtu 1500
priority: 0
groups: tun vpn egress
status: active
inet 10.1.1.1 --> 10.1.1.2 netmask 0xfffffffc



J'ai une bizarrerie en lieu et place de ça: j'ai la même adresse aux deux
bouts, selon la sortie de mon ifconfig. Pourtant, le tunnel est utilisable
depuis le routeur ?!? Je vais creuser ça.

Et finalement mon pf.conf:
set skip on lo

relais = "173.194.66.100"
tport = "{www, https}"
uport = "{domain}"

match out proto tcp from phy to $relais port $tport
rdr-to vpn:peer
pass out quick proto tcp from phy to vpn:peer port $tport
nat-to vpn



Peux-tu me confirmer qu'ici, vpn est un nom de groupe d'interfaces, comme
décrit dans man ifconfig?

Voilà (je sais pas si ça peut aider en fait.)



Ça donne matière à creuser, merci. :-)

--
Étienne
Avatar
Manuel Giraud
Etienne writes:

Et finalement mon pf.conf:
set skip on lo

relais = "173.194.66.100"
tport = "{www, https}"
uport = "{domain}"

match out proto tcp from phy to $relais port $tport
rdr-to vpn:peer
pass out quick proto tcp from phy to vpn:peer port $tport
nat-to vpn



Peux-tu me confirmer qu'ici, vpn est un nom de groupe d'interfaces, comme
décrit dans man ifconfig?



Oui. En fait ça correspond au groupe auquel appartient mon tun0. Je sa is
pas si c'est la façon de faire la plus jolie mais pf comprend bien à §a.
Voilà le contenu de mon /etc/hostname.tun0 qui fait ça:
inet 10.1.1.1 255.255.255.252 10.1.1.2 group vpn

--
Manuel Giraud
Avatar
Etienne
Ce bavard de Etienne vient de nous dire:

Bon, j'ai pris le temps de me repencher sur mon problème, et je poste
pour documenter les archives, vu le peu que j'ai trouvé sur le net qui
corresponde à ma situation.

Résumé des épisodes précédents: J'ai un routeur OpenBSD qui créé un
tunnel OpenVPN dont je ne contrôle pas la configuration. Au contraire
des exemples les plus répandus, je ne veux rediriger qu'une partie de
mon traffic, filtrée par PF à travers ce tunnel. Ma route par défaut
n'est donc _pas_ l'autre bout du tunnel.

$ ifconfig tun0
tun0: flagsQ<UP,POINTOPOINT,RUNNING> mtu 1500
priority: 0
groups: tun vpn egress
status: active
inet 10.1.1.1 --> 10.1.1.2 netmask 0xfffffffc



J'ai une bizarrerie en lieu et place de ça: j'ai la même adresse aux deux
bouts, selon la sortie de mon ifconfig. Pourtant, le tunnel est utilisable
depuis le routeur ?!? Je vais creuser ça.



Comme mentionné ci-dessus:

# ifconfig tun0
tun0: flags€51<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1500
priority: 0
groups: tun
status: active
inet 196.225.61.142 --> 196.225.61.142 netmask 0xffffff80

(adresse IP modifiée)

Disons que j'ai choisi de faire passer par le tunnel tout le traffic
issu de $machineA. Mon interface interne est sis0, et mon réseau local
est représenté par $int_lan. Les règles PF qui en découlent sont:

match out quick on tun0 from $machineA to !$int_lan
nat-to (tun0)

Du NAT tout bête, et:

pass in quick on sis0 from $machineA to !$int_lan
route-to (tun0 $vpn_gw)

De ce que j'ai compris, habituellement, le deuxième argument de
route-to est optionel. Dans mon cas, visiblement, il est nécessaire,
et je suppose l'indice était dans la sortie de "ifconfig tun0", qui
montre la même adresse aux deux bouts du tunnel. Pour savoir comment
définir $vpn_gw, j'ai fouillé dans les logs de OpenVPN: Il se trouve
qu'une route par défaut est donnée dans la réponse du serveur.

Ces deux règles permettent de faire sortir du traffic du réseau local,
mais pas d'en faire rentrer. Pour ça, on a:

match in inet proto tcp from any to tun0 port http
rdr-to $machineA
pass in inet proto tcp from any to $machineA port http

Habitué à appliquer des règles PF à une interface ("on tun0", "on sis0"),
j'ai mis un petit moment à réaliser qu'il n'est pas nécessaire (et
d'ailleurs impossible) de le faire ici. Le "port http" n'est là que pour
donner un exemple de filtrage.

Oualà.

--
Étienne