Port Forwarding FROM CHR

Hi everyone. I have a client under NAT, on which there is a server that I would like to reach remotely. Having a CHR with a public IP, I thought of establishing a wireguard tunnel between the offices and creating a dstnat in the chr towards the server using static routes to reach it. In the same way I would like to use a mixed routing table, so that the server goes out on the internet with the public IP of its client-side router but is reached by the public IP of the CHR. I tried to work with the client-side mangle, creating these rules, but I think I’m doing something wrong.

/routing table add tablet=to-WG fib=yes

/ip firewall mangle
add chain=forward dst-address=192.168.170.2 protocol=tcp dst-port=443 action=new-connection-mark=wg-conn
add chain=prerouting connection-mark=wg-conn action=mark-routing new-connection-mark=to-WG

/ip route add gateway=10.120.10.1 routing-table=to-WG

where 192.168.170.2 is the server IP and 10.120.10.1 is the wireguard IP on the chr side

Firstly we are not in your head… Which MT device is the peer Server for handshake and which MT entity is the peer Client for handshake???

You have to clarify the point in Green to me below…it makes no sense.
a. public IP on main HOME Router ( or have an IPS router that can forward ports to it…
b. public IP (usually static) on CHR in the cloud.
c. Have a server on the HOME ROUTER which you would like:

1 → server clients reach the SERVER via CHR, which port forwards the request via a WIreguard tunnel to the HOME ROUTER.
2–> server reaches out to the internet via the main routers internet ???

This makes no sense, a SERVER does not originate traffic out to the net.
Also, if your MT router is capable of hosting wireguard, why not have users connect securely via wireguard to your router directly and then access the server. ( to many users?? )

Finally, for any assistance post both configs..
/export file=anynameyouwish (minus router serial number, any publicWANIP information, keys etc.)

The idea is fine, what kills it is that the action=mark-routing rule does not care about packet direction. So

  • the first packet that comes in via the WG tunnel from the client gets routed to the 192.168.170.2 via LAN and after routing it causes the connection to get marked with wg-conn.
  • the response to it gets marked with to-WG and routed to the WG tunnel - that’s still fine.
  • the next packet from the client matches all the criteria of the current action=mark-routing rule as well so instead of getting to the server, it is routed back to the WG tunnel - oops…

So just add in-interface=LAN or in-interface=!WG or src-address=192.168.170.2 to the action=mark-routing rule and you should be good.

Technicalities aside…
Why would someone need to mangle SERVER traffic responses back out wireguard from a CHR connection.

One simply sourcenats the original inquiries coming into the tunnel at the CHR and the responses flow back from the server no problem, no fuss.
One reason I can come up with, is that the OP also wants to be able to response to SERVER inquiries from their own local WAN at the same time and thus one has to separate the CHR incoming traffic out separately via mangles. So the server serves both incoming traffic from the local WAN and through the CHR.

BUT… that is NOT what the op articulated.
quote: “so that the server goes out on the internet with the public IP of its client-side router but is reached by the public IP of the CHR” unquote.

In other words he wants clients to request access to the server (send packets to the server ) via the CHR connection ( port forwarded into wireguard tunnel ) and then possibly have the responses returned to the originator out the local WAN of the router. This is nonsensical enough, as much as the the thought of the Server originating traffic.

So, why the heck correct an incorrect premise???
Instead of seeking first the clarity of what is actually going on and what is actually the expectation of the OP, to derive what is the actual requirement and then come up with a feasible configuration???

+++++++++++++++++++++++++++++++++++++++++++++++++++

On another tangent, another reason one might have to mangle incoming port forwarded traffic, is IF, the server for some reason (logging/records) needs to see the actual source IP of the incoming user to the server via CHR/wireguard. In this case, sourcenat at the CHR would not be used and mangling would have to on the MAIN home router to ensure the originator traffic would get back through the tunnel to the CHR. However, one could equally state, get your logging done when the user first hits the CHR with its originating address for records etc…

Finally, this is only one snippet of the Ops config, and one teeeny tiny eeny weeny, itsy bitsy part of the Ops requirements, and likely the config requires a holistic appreciation to ensure the very specific mangling advice actually fits and makes sense in the overall config.

/export file=anynameyouwish ( minus router serial number, any public WANIP information, keys etc. )

I apologize if I expressed myself badly, but what Sindy indicated made the difference.

In any case, the CHR configuration is:

/interface wireguard
add listen-port=13231 mtu=1420 name=wireguard1
/interface vlan
add interface=ether1 name=vlan80 vlan-id=80
/interface pppoe-client
add add-default-route=yes disabled=no interface=vlan80 name=pppoe-out1 user=c1v
/interface wireguard peers
add allowed-address=0.0.0.0/0 client-address=10.120.10.2/32 client-endpoint=1.2.3.4 client-keepalive=25s client-listen-port=13231 interface=wireguard1 persistent-keepalive=25s \
    private-key="ABCDEFGHIJKLMNOPQRSTUVWYZ123456789=" public-key="ABCDEFGHIJKLMNOPQRSTUVWYZ123456789="
/ip address
add address=10.120.10.1/30 interface=wireguard1 network=10.120.10.0
/ip dns
set allow-remote-requests=yes servers=1.1.1.1
/ip firewall filter
add action=accept chain=input connection-state=established,related
add action=drop chain=input connection-state=invalid
add action=accept chain=input in-interface=pppoe-out1 protocol=icmp
add action=accept chain=input dst-port=13231 in-interface=pppoe-out1 protocol=udp
add action=drop chain=input in-interface=pppoe-out1
/ip firewall nat
add action=dst-nat chain=dstnat dst-address=1.2.3.4 dst-port=80,8291 protocol=tcp to-addresses=192.168.170.2
add action=masquerade chain=srcnat out-interface=pppoe-out1
/ip route
add disabled=no dst-address=192.168.170.2/32 gateway=10.120.10.2 routing-table=main suppress-hw-offload=no
/system identity
set name=CHR

In any case, the configuration of the home router:

/interface wireguard
add listen-port=13231 mtu=1420 name=wireguard1
/port
set 0 name=serial0
/routing table
add disabled=no fib name=out-CHR
/interface wireguard peers
add allowed-address=0.0.0.0/0 client-address=10.120.10.1/32 endpoint-address=1.2.3.4 endpoint-port=13231 \
    interface=wireguard1 persistent-keepalive=25s private-key="ABCDEFGHIJKLMNOPQRSTUVWYZ123456789=" \
    public-key="ABCDEFGHIJKLMNOPQRSTUVWYZ123456789="
/ip address
add address=10.120.10.2/30 interface=wireguard1 network=10.120.10.0
add address=192.168.170.1/24 interface=ether2 network=192.168.170.0
/ip dhcp-client
add interface=ether1
/ip firewall filter
add action=accept chain=input connection-state=established,related
add action=drop chain=input connection-state=invalid
/ip firewall mangle
add action=mark-connection chain=prerouting dst-address=192.168.170.2 dst-port=80,8291 new-connection-mark=chr-conn \
    passthrough=yes protocol=tcp
add action=mark-routing chain=prerouting connection-mark=chr-conn in-interface=!wireguard1 new-routing-mark=out-CHR \
    passthrough=yes
/ip firewall nat
add action=masquerade chain=srcnat out-interface=wireguard1 src-address=192.168.170.2
add action=masquerade chain=srcnat out-interface=ether1
/ip route
add disabled=no dst-address=0.0.0.0/0 gateway=10.120.10.1 routing-table=out-CHR suppress-hw-offload=no
/system identity
set name=CASA

regarding the first rule which deals with the mark connection, would chain forward or prerouting be more correct?

everything works with both chains

With so many occurrences of “the X/Y problem” phenomenon, @anav prefers to have a complete description of the functional requirements from the user perspective and then offer the simplest solution from his catalogue that fulfils them, even if it means redoing the configuration from scratch.

Using a src-nat on the CHR side as you send the traffic to the on-site router as @anav suggested would make the on-site server see the requests coming from any address in the internet as coming from the CHR’s address in the Wireguard subnet, so no policy routing on the on-site routing would be necessary. But the price to pay for this simplicity is the loss of information about the actual source IP address of the incoming requests - in some cases this doesn’t matter, in some cases it is a show stopper. There is also another limitation caused by such an approach, but I don’t expect that there would be thousands of connections per minute so exhausting the whole range of ephemeral ports at the CHR side would cause any issues.

@anav, on the on-site router it is just the classical scenario where you have multiple WANs with public addresses and you want the on-site router to forward the resonses of a server on a private address in LAN through the correct WAN. The only difference is that here, the second WAN is the WG tunnel and the associated NAT is done at the CHR rather than locally. Think of it the same as a CGNAT setup where the WAN address is a non-public one and the ISP does the NAT, except that few ISPs provide dst-nat for clients (some do, you get e.g. 3 TCP ports and 3 UDP ones on a fixed public address forwarded to your CGNAT IP and it’s up to you what you use them for).


Here in particular it does not matter, as the connection mark doesn’t change the way the initial packet is routed. So neither way is “correct” or “wrong”. In other scenarios, you need already the initial packet that causes the connection-mark to be assigned to be routed in accord with the connection mark, and there, it must be assigned in prerouting, before it is used to set a routing mark. But in yet other scenarios, you can assign the routing mark directly, without assigning a connection-mark first.

" But the price to pay for this simplicity is the loss of information about the actual source IP address of the incoming requests - in some cases this doesn’t matter, in some cases it is a show stopper.
Why not simply log the users hitting the port forwarding rule on the CHR to fulful the admins need to know what source addresses are being sent to the server and thus keeping the sourcenatting at the CHR?

As for the configs, what kind of CHR cloud based service is that? Most cloud hosted CHRs are fixed public IPs, not pppoe connections…
So perhaps I am wrong.

Should I assume the CHR is on a computer at a completely different site???
In any case I take issue with wireguard settings.
Edit: Okay I see that both need allowed IPs of 0.0.0.0/0 not the usual setup.
The way I recommended the setup, only the wireguard IP of the CHR would be defined on the home router device settings and would allow concurrent admin and any joe user on the same tunnel.
What is the actual need of the server???

However, one does not need persistent keep alive and endpoint information on both sides, or at least I dont see the value in that and using the same listening port even more confusing.
I am assuming you have truncated your actual firewall rules because the router is wide open otherwise…

+++++++++++++++++++++++++++++++++++++++++++
The solution sindy suggested, a bit different maybe.

HOME ROUTER
/ip route
add address=0.0.0.0/0 gateway=homerouterISP_gateway IP table=main
add address=0.0.0.0/0 gateway=wireguard1 table=out-CHR

/ip nat mangle
add chain=forward action=mark-connections connection-mark=no-mark in-interface=wireguard1
destination address=192.168.170.2 dst-port=80 protocol=tcp new-connection-mark=for-server passthrough=yes
add chain=prerouting action=mark-routing connection-mark=for-server
new-routing-mark=out-CHR passthrough=no

+++++++++++++++++++++++++++++++++++++++++++++++++++


Now to fix your 8291 problem… besides being unsafe, delineating tcp for a udp protocol would not get you far… like giving sindy an enema with a toothpick, at least use a straw… :slight_smile:

CHR ROUTER
/interface wireguard
add listen-port=13231 mtu=1420 name=wireguard1
add listen-port=15677 mtu=1420 name=wireguard-Admin

/interface wireguard peers
add allowed-address=0.0.0.0/0 client-address=10.120.10.2/32 client-endpoint=1.2.3.4 client-keepalive=25s client-listen-port=13231 interface=wireguard1 persistent-keepalive=25s
private-key=“ABCDEFGHIJKLMNOPQRSTUVWYZ123456789=” public-key=“ABCDEFGHIJKLMNOPQRSTUVWYZ123456789=”
add allowed-address=10.10.70.2,192.168.170.0/24 interface=wireguard-Admin public-key=“----” comment=“home router”
add allowed-address=10.10.70.3 interface=wireguard-Admin public-key=“^^^” comment=“admin remote laptop”

/ip address
add address=10.120.10.2/30 interface=wireguard1 network=10.120.10.0
add address=10.10.70.1/29 interface=wireguard-Admin network=10.10.70.0

/ip firewall nat
add action=dst-nat chain=dstnat dst-address=1.2.3.4 dst-port=80 protocol=tcp to-addresses=192.168.170.2
add action=masquerade chain=srcnat out-interface=pppoe-out1

/ip firewall
add action=accept chain=input comment=“wg handshake” dst-port=15677 protocol=udp
add action=accept chain=input comment=“admin access” in-interface=wireguard-Admin
add action=accept chain=forward comment=“relay remote admin” in-interface=wireguard-Admin out-interface=wireguard-Admin

/ip route
add dst-address=192.168.170.0/24 gateway=wireguard1 table=main ( allows both incoming users to server but also admin on to access home LAN )

HOME ROUTER
/interface wireguard
add listen-port=13231 mtu=1420 name=wireguard1
add listen-port=12345 mtu=1420 name=wireguard-Trusted

/interface wireguard peers
add allowed-address=10.10.70.0/29 endpoint=chr-public-ip endpoint-port=15677 interface=wireguard-Trusted persistent-keepalive=35s
public-key=“#####”

/ip address
add address=10.120.10.1/30 interface=wireguard1 network=10.120.10.0
add address=10.10.70.2/29 interface=wireguard-Trusted network=10.10.70.0

/ip firewall
add action=accept chain=input comment=“admin access” in-interface=wireguard-Trusted
add action=accept chain=forward comment=“admin access” in-interface=wireguard-Trusted out-interface-list=LAN
( or whatever is appropriate to reach )

I am currently testing the configuration on a local chr on which I receive a public IP from the ISP. Then the configuration will go into production on CHR in CLOUD with static public IP without pppoe. the Wireguard tunnel has allowed address 0.0.0.0/0 as I did not want it to create limitations in this lab, in production then only the necessary IP will be inserted. the Listen Port of the Home Router, I believe it is not important as it is not reachable from the outside being under NAT. I did not insert the complete configurations from the beginning as the focal point was the issue of the mangle, so it did not seem necessary to indicate everything. However, for correctness I inserted it and this created confusion in my opinion. Could you explain to me what you mean by this?

However, one does not need persistent keep alive and endpoint information on both sides

Port 8291 is exposed because it is a test lab that would be exposed for a short time. In the production configuration there is already a wireguard to reach the sites without having to expose ports. The application of exposing the server ports is something wanted beyond the risks and reachability Wireguard

Okay, sounds like you have it well in hand.
As to keep alive, ONLY the peer client for handshake ( the initiator of the conversation) requires persistent keep alive, the peer server for handshake does not.