TL;DR : Sur Mojave (je n'ai pas testé sur d'autres), lors de la création de rdr
règles en pf
les règles fonctionnent pendant un certain temps (avec quelques problèmes d'accès direct au port cible), mais après un certain temps, les règles cessent de fonctionner, bien que je ne puisse pas faire en sorte que les règles soient appliquées. pfctl
signaler toute chose différemment de manière à ce qu'il soit évident qu'elles ne s'appliquent plus.
J'ai créé /Library/LaunchDaemons/dev.up.pfctl.plist
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Disabled</key>
<false/>
<key>Label</key>
<string>dev.up.pfctl</string>
<key>WorkingDirectory</key>
<string>/var/run</string>
<key>Program</key>
<string>/sbin/pfctl</string>
<key>ProgramArguments</key>
<array>
<string>pfctl</string>
<string>-e</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
...et /Library/LaunchDaemons/dev.up.loopbackalias.plist
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>dev.up.loopbackalias.plist</string>
<key>RunAtLoad</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>/sbin/ifconfig</string>
<string>lo0</string>
<string>alias</string>
<string>127.0.0.42</string>
</array>
</dict>
</plist>
J'ai ajouté ce qui suit à /etc/pf.conf
:
# allow nginx to bind on :20080 instead of :80, and :20443 instead of :443.
# This allows us to run it as the non-root user, and thus not require
# auth to update/restart it.
rdr pass on lo0 inet proto tcp from any to 127.0.0.42 port 80 -> 127.0.0.42 port 20080
rdr pass on lo0 inet proto tcp from any to 127.0.0.42 port 443 -> 127.0.0.42 port 20443
...et j'ai nginx qui tourne et qui est lié à 127.0.0.42:20080
et 127.0.0.42:20443
.
Lorsque j'applique la configuration en redémarrant ou en exécutant la commande pfctl -f /etc/pf.conf
, les choses fonctionnent :
$ curl http://127.0.0.42:80/services/ping
ok
Cependant...
Problème 1
Lorsque cette règle est active, l'accès direct au port cible (20080/20443) pose des problèmes intéressants. Il y a un délai d'accès qui semble augmenter rapidement avec le nombre d'accès (récents ?):
$ time curl -s -o /dev/null http://127.0.0.42:20080/services/ping
(0.2 seconds)
$ time curl -s -o /dev/null http://127.0.0.42:20080/services/ping
(1.6 seconds)
$ time curl -s -o /dev/null http://127.0.0.42:20080/services/ping
(27 seconds)
$ time curl -s -o /dev/null http://127.0.0.42:20080/services/ping
(timeout)
(toutefois, tout au long de la procédure, l'accès :80
-le port redirigé par pf
a :20080
-fonctionne et prend <25ms.)
Problème 2
Au bout d'un certain temps, la règle de redirection cesse complètement de s'appliquer, comme si pf
n'ont pas été activées du tout ou la règle n'a pas été chargée, mais elle prétend toujours être activée et je la vois toujours signalée par pf
:
$ pfctl -s nat
No ALTQ support in kernel
ALTQ related functions disabled
nat-anchor "com.apple/*" all
rdr-anchor "com.apple/*" all
rdr pass on lo0 inet proto tcp from any to 127.0.0.42 port = 80 -> 127.0.0.42 port 20080
rdr pass on lo0 inet proto tcp from any to 127.0.0.42 port = 443 -> 127.0.0.42 port 20443
$ pfctl -s info | grep Enabled
No ALTQ support in kernel
ALTQ related functions disabled
Status: Enabled for 6 days 14:56:42 Debug: Urgent
$ curl -s http://127.0.0.42:80/services/ping
curl: (7) Failed to connect to 127.0.0.42 port 80: Connection refused
$ curl -s http://127.0.0.42:20080/services/ping
ok
Je peux le déclencher de manière assez fiable en me déconnectant du WiFi. Je pense que cela ne se produit probablement que lorsque des changements sont apportés au réseau.