Short version
Server A (OpenBSD 4.7) connects to server B (Windows). IP of server B changes. Server A should be able to connect to server B to both the old and new IP. We cannot configure multiple IPs on server B.
Long version
We have an OpenBSD server acting as an access point (ssh + authpf rules) where external clients connect and then open a connection to a service on another internal server. The internal server IP is going to change.
To give us more time to reconfigure all clients to use the new IP address, I thought we can implement the equivalent of a DNAT on the OpenBSD box. If this was a Linux box, I could use the following DNAT rule which lets me connect out from the box itself to the remote service on either the real IP (10.68.32.215) or the new IP.
$ sudo iptables -t nat -A OUTPUT -d 10.68.99.99 -j DNAT --to-dest 10.68.32.215
$ ssh-keyscan -t rsa 10.68.32.215
# 10.68.32.215 SSH-2.0-OpenSSH_4.3
10.68.32.215 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAy/GCd47aaRkBOu72v9Ysqk48Ngd6budStvdwnvMOTLiYoz6M81cTq7SskWctXx57cz6Ijnv1sbzcmDpFMUsN5vHk+6NxfrLzO0M1zh7UezY54FakgaavSdCiy15vGw/Lifntp5kMKkjgC5o42O+RUVw5iCpR8nsu/2/kR2smcVR1G3R8EunjCZWEptOCHz3Iup7FTMd4Pw/xmt+8u+5ZyHKu+uaLWQl6I12rzLiQJNyMLVdhba54FGiJDFUfcXtgM7cFli6xlrE3dnbboQE/7/cuj/N11QwTvHuU07NtrubefZE1VahWb146ph31blsW5NSiyFwL2I7rxFFoPQMbuQ==
$ ssh-keyscan -t rsa 10.68.99.99
# 10.68.99.99 SSH-2.0-OpenSSH_4.3
10.68.99.99 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAy/GCd47aaRkBOu72v9Ysqk48Ngd6budStvdwnvMOTLiYoz6M81cTq7SskWctXx57cz6Ijnv1sbzcmDpFMUsN5vHk+6NxfrLzO0M1zh7UezY54FakgaavSdCiy15vGw/Lifntp5kMKkjgC5o42O+RUVw5iCpR8nsu/2/kR2smcVR1G3R8EunjCZWEptOCHz3Iup7FTMd4Pw/xmt+8u+5ZyHKu+uaLWQl6I12rzLiQJNyMLVdhba54FGiJDFUfcXtgM7cFli6xlrE3dnbboQE/7/cuj/N11QwTvHuU07NtrubefZE1VahWb146ph31blsW5NSiyFwL2I7rxFFoPQMbuQ==
Our version of OpenBSD is 4.7, but we can upgrade if necessary. If this DNAT is not possible we can probably do a NAT on a firewall along the way.
The closest I was able to accomplish on a test box is:
pass out on em1 inet proto icmp from any to 10.68.31.99 nat-to 10.68.31.247
Unfortunately, pfctl -s state
tells me that nat-to
translates the source IP, while I need to translate the destination.
$ sudo pfctl -s state
all icmp 10.68.31.247:7263 (10.68.30.199:13437) -> 10.68.31.99:8 0:0
I also found lots of mentions about rules that start with rdr
and include the ->
symbol to express the translation, but it looks like this syntax has been obsoleted in 4.7 and I cannot get anything similar to work. Attempts to implement a new-syntax redirect rule fail with:
$ echo match out on em1 to 10.68.31.99 rdr-to 10.68.31.247 | sudo pfctl -f -
stdin:1: rdr-to can only be used inbound
Of course, since I am trying to redirect outgoing traffic, modifying the above rule to "pass in" does not work either.
Current status
Ended up applying a NAT on a firewall between the two servers. Did the trick, though from academic interest, I am still curious if this is doable in OpenBSD.
I'm not totally sure if that's what you want but I use something likt this to redirect traffic to another IP.
The syntax is not tested but might work
Something similar works on FreeBSD
Edit
After a look into the OpenBSD manpages this syntax might work:
I don't think
pf
can do this.pf
has 4 ways to alter packets:route-to
(andreply-to
) optionnat
rulebinat
rulerdr
is stateful, I don't understand whybinat
exists.)rdr
ruleI was trying to redirect outgoing packets with destination
10.193.130.31.56862
to10.0.0.30.56862
. I was able to do this on linux withiptables
:I tried to do the same on
macOS
by adding to my/etc/pf.conf
:where
en6
is my external network interface.I then added a logging interface with:
Finally, I reloaded my
pf
rules with:And started
pf
with:And then my packets with
tcpdump
:I created a test connection with:
And I saw the following output in
tcpdump
:Which indicates that my source was changed to
10.0.0.30:56862
, but not my destination.When I ran similar tests with an
rdr
rule, I got no output (because I had no incoming packets):