Только с NAT - нет. IP-пакеты имеют только одно поле «источник».
Если вы заставите iptables сохранить исходный адрес клиента (только DNAT), то yyyy попытается отправить ответы непосредственно этому исходному клиенту (который думает, что он разговаривает с xxxx и не ожидает никаких пакетов от yyyy).
Если вы сделаете так, чтобы iptables указывал ваш адрес в качестве нового источника (DNAT+SNAT), то yyyy не будет знать исходный адрес источника.
(Это на самом деле та же проблема, что и при попытке перенаправить порт из локальной сети в ту же локальную сеть, и второй метод называется «закрепление NAT» или «отражение NAT».)
Чтобы это работало, вам нужен туннель /VPN между xxxx и yyyy - оберните исходные пакеты, которые вы получаете, без каких-либо изменений, в другой IP-пакет, который отправляется в yyyy (который затем развернет туннельный пакет и увидит исходный источник),
Конечно, это означает, что вам нужны права суперпользователя в обеих системах для настройки туннеля. Кроме того, пункт назначения (гггг) должен поддерживать "маршрутизацию политик" - Linux и FreeBSD pf способны на это. Требуется правило, которое будет направлять все через VPN, если адрес источника является адресом VPN.
Вам все еще нужно правило DNAT iptables, но его «пунктом назначения» будет VPN-адрес, а не публичный адрес. Для этого вы можете использовать любой тип туннеля /VPN, от базового «IP-in-IP» до GRE, от OpenVPN до WireGuard. Например:
хххх
Поднимите туннель:
ip link add gre-y type gre local x.x.x.x remote y.y.y.y ttl 64
ip link set gre-y up
ip addr add 192.168.47.1/24 dev gre-y
Добавьте правило переадресации портов, как в локальной сети:
iptables -t nat -I PREROUTING -p tcp --dport 1234 -j DNAT --to-destination 192.168.47.2
гггг
Поднимите туннель:
ip link add gre-x type gre local y.y.y.y remote x.x.x.x ttl 64
ip link set gre-x up
ip addr add 192.168.47.2/24 dev gre-x
Убедитесь, что это работает:
ping 192.168.47.1
Настройте политику маршрутизации, чтобы ответы (и только ответы) проходили через туннель:
ip route add default via 192.168.47.1 dev gre-x table 1111
ip rule add pref 1000 from 192.168.47.2 lookup 1111
(Чтобы использовать другой тип туннеля /VPN, замените только часть "Bring up the tunnel".)