Bypass CGNAT using CHR Relay Server - Need help

Hello,

I have a CHR hosted on cloud with a public IP.

Also i have 3 different sites using starlink as their WAN and they have CG-Natted IP so i can’t reach them directly. I have 2 different needs.

i want few road warrior clients to reach their router’s LAN through chr

the second need is that i have a pbx behind router 1 and i want to port forward few ports. Is it posible only the PBX (192.168.100.250 lan IP) to routed through CHR and use its public IP in order to perform port forwarding from CHR?

Can anyone help me to clear the configurations i need in my mind? i am thinking using wireguard for the tunnels. Do you recommend any other protocol?

You have to find out the UDP port range the PBX uses for RTP (or set it if such a setting is available) so that it would not clash with the UDP ports used for the Wireguard or IPsec connections. You also have to tell the PBX the public IP so that it could put it into the SIP messages.

If you don’t mind that Wireguard is limited to a single encryption and authentication algorithm and the “server” side cannot push any configuration to the “clients”, there is nothing wrong about using it for the setup you plan on.

So if the LAN subnets on the three sites do not overlap and you use yet another non-overlapping range to assign addresses to the road warrior devices, there should be nothing complicated about this setup. I would probably use one Wireguard interface for the road warriors and another one for the routers because it makes the topology a little more clear, but it is not a must.

the pbx RTP ranges are from 10000-12000 and i also need udp 5060. the default 13231 of WG is outside the rage so i suppose it’s ok to use.

I don’t know how to create the tunnels (with what configuration for each router and on chr) i am very confused on that part. can we try a demo example configuration?

Is there any easier to manage vpn protocol for this kind of setup? instead of wg i mean?

Configuration-wise, the simplest one is SSTP but it needs certificates (or at least it is quite insecure not to use them). L2TP/IPsec is equally easy to set up as SSTP if you are happy with the defaults for encryption and authentication. Bare IPsec is powerful but by far the most complicated to grasp the concept (rather than just configure, once you get the concept, the configuration is not that complicated per se).

So why not Wireguard.

You have three keys: the private one, the public one (each peer has an own pair of these) and optionally the pre-shared one which is common for both peers; unlike IPsec, the pre-shared key is used together with the private/public pairs, not instead of them.

Each peer signs the authentication messages using its private key; anyone who has got (offline) the matching public key can verify the identity of the sender of these messages by verifying the signature using the public key.

So when adding a Wireguard interface, you do not specify either of the keys, the system generates the private key automatically, and computes also the matching public one. When configuring a peer, you set the public key value to the one of the remote “interface”. So for the CHR and Starlink-1, the configuration will look as follows:

CHR:
/interface/wireguard/add name=wg1
/interface/wireguard/print

Ctrl-C the value of public-key

Starlink-1:
/interface/wireguard/add name=wg1
/interface/wireguard/peers/add interface=wg1 public-key= endpoint-address=ip.of.the.chr endpoint-port=13231 allowed-address=0.0.0.0/0 persistent-keepalive=30s
/interface/wireguard/print

Ctrl-C the value of public-key

CHR:
/interface/wireguard/peer add interface=wg1 public-key= is-responder=yes allowed-address=lan.subnet.of.starlink-1/mask-length

After this, the Wireguard connection should go up. Next, you must set up the routing - on the CHR, you add a route dst-address=lan.subnet.of.starlink-1 gateway=wg1; on the Starlink-1 router, you add routes to all the other LAN subnets as well as the range of road warrior addresses via wg1.

On the Starlink-X to which the PBX is connected, you will need to use policy routing:
/routing/table/add via-wg fib
/ip/route/add gateway=wg routing-table=via-wg
/routing/rule/add src-address=ip.of.the.pbx action=lookup-only-in-table table=main min-prefix=0
/routing/rule/add src-address=ip.of.the.pbx action=lookup-only-in-table table=via-wg

The purpose is that the PBX would use the default route via the Wireguard tunnel but still could talk to local destinations.

Hello again,

i have performed the setup connecting the starlink-1 to CHR and i did the policy routing. from chr i can ping the local pbx ip. Then i perfomed on the chr router a port forward rule to local pbx ip(the pbx web interface in order to check if forwarding works) but i cannot reach it from the CHR’s public ip. Do i need any other nat rules on the starlink-1 side? I have masquarade rule on both routers (CHR and Starlink-1)

Post both configs. CHR and first starlink
/export file=anynameyouwish ( minus device serial number, any public WANIP information, keys ).

To be clear on requirements.

There are two sets of road warriors.
a. those that need access to LANS on each starlink.
b. ADMIN that needs access to LANS too but more imporantly able to CONFIGURE each starlink router
c. Need to port forward a few ports to PBX, since I dont have one of those…
a. do local users on associated starlink need access to PBX?
b. do other users on the other 2 starlink LANS need access to the PBX
c. any other users of PBX??

Question: Do any starlink users or roadwarrior etc, require go out internet of CHR, or all users are just fine using their local starlink WAN for internet traffic?
( we know PBX is exception as it should only use CHR for outbound internet traffic)

You also have to tell the PBX the public IP so that it could put it into the SIP messages.

this is the most important point.

sip registration needs to know open ports for communication to establish. on both sides (the caller and receiver).

making the chr as proxy to re route the sip registration process is doing nothing to help the real communication to establish on cgnatted networks. since sip call is direct communication between 2 parties.

for simplicity - put/rent the pbx on the cloud.

I have set up the pbx with the CHR’s public ip and the nat settings.

i haven’t setup roadwarriors yet, just the tunnel and the routing from starlink router to chr and the opposite.
The pbx has internet connectivity, i can trace route and ping external hosts but i tried to expose the web UI of pbx in order to check the port forward and i cannot reach it. also the nat rule on chr doesn’t have traffic.

the CHR config is bellow:

/interface ethernet
set [ find default-name=ether1 ] disable-running-check=no
/interface wireguard
add listen-port=13231 mtu=1420 name=ChatziS2S
/interface list
add name=WAN
/port
set 0 name=serial0
/ip neighbor discovery-settings
set discover-interface-list=none
/interface list member
add interface=ether1 list=WAN
/interface wireguard peers
add allowed-address=192.168.2.0/24 interface=ChatziS2S name=toHQ public-key=\
    "Nvrfvgbvhvgvfrvrfv" responder=yes
/ip address
add address=172.16.100.1/24 interface=ChatziS2S network=172.16.100.0
/ip cloud
set ddns-enabled=yes update-time=yes
/ip dhcp-client
add interface=ether1
/ip firewall filter
add action=accept chain=input dst-port=8292 protocol=tcp
add action=accept chain=input dst-port=13231 protocol=udp
add action=accept chain=input comment=\
    "defconf: accept established,related,untracked" connection-state=\
    established,related,untracked
add action=accept chain=input comment="Allow management from trusted IP" \
    src-address=91.91.91.91
add action=drop chain=input comment="defconf: drop invalid" connection-state=\
    invalid
add action=accept chain=input comment="Allow loopback" in-interface=lo
add action=drop chain=input comment="Drop all other inbound traffic"
add action=accept chain=forward in-interface=ChatziS2S
add action=accept chain=forward comment=\
    "defconf: accept established,related, untracked" connection-state=\
    established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" \
    connection-state=invalid
add action=drop chain=forward comment=\
    "defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat \
    connection-state=new in-interface-list=WAN
/ip firewall nat
add action=masquerade chain=srcnat out-interface-list=WAN
add action=masquerade chain=srcnat disabled=yes out-interface=ChatziS2S
add action=dst-nat chain=dstnat dst-port=18111 protocol=tcp to-addresses=\
    192.168.2.200 to-ports=8111
add action=dst-nat chain=dstnat dst-port=8090 protocol=tcp to-addresses=\
    192.168.2.200 to-ports=8088
add action=dst-nat chain=dstnat dst-port=18111 protocol=udp to-addresses=\
    192.168.2.200 to-ports=8111
add action=dst-nat chain=dstnat dst-port=6023 protocol=udp to-addresses=\
    192.168.2.200 to-ports=5060
add action=dst-nat chain=dstnat dst-port=10000-12000 protocol=udp \
    to-addresses=192.168.2.200 to-ports=10000-12000
/ip firewall service-port
set ftp disabled=yes
set tftp disabled=yes
set h323 disabled=yes
set sip disabled=yes
set pptp disabled=yes
/ip route
add disabled=no distance=1 dst-address=192.168.2.0/24 gateway=ChatziS2S \
    routing-table=main scope=30 suppress-hw-offload=no target-scope=10
/ip service
set telnet disabled=yes
set ftp disabled=yes
set www disabled=yes
set ssh disabled=yes
set api disabled=yes
set winbox address=91.91.91.91/32 port=8292
set api-ssl disabled=yes
/system clock
set time-zone-name=Europe/Helsinki
/system note
set show-at-login=no
/tool mac-server
set allowed-interface-list=none
/tool mac-server mac-winbox
set allowed-interface-list=none
/tool mac-server ping
set enabled=no

This is the starlink-1:

/interface bridge
add admin-mac=XXX.XXX.XXX.XXX.XXXX auto-mac=no comment=defconf name=bridge
/interface wireguard
add listen-port=13231 mtu=1420 name=SysConCHR
/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
/ip pool
add name=dhcp_pool1 ranges=\
    192.168.2.100-192.168.2.199,192.168.2.201-192.168.2.230
/ip dhcp-server
add address-pool=dhcp_pool1 interface=bridge lease-time=1d name=dhcp1
/port
set 0 name=serial0
/routing table
add disabled=no fib name=toCHR
/disk settings
set auto-media-interface=bridge auto-media-sharing=yes auto-smb-sharing=yes
/interface bridge port
add bridge=bridge comment=defconf interface=ether3
add bridge=bridge comment=defconf interface=ether4
add bridge=bridge comment=defconf interface=ether5
add bridge=bridge comment=defconf interface=ether6
add bridge=bridge comment=defconf interface=ether7
add bridge=bridge comment=defconf interface=ether8
add bridge=bridge comment=defconf interface=sfp1
/ip neighbor discovery-settings
set discover-interface-list=LAN
/interface list member
add comment=defconf interface=bridge list=LAN
add comment=defconf interface=ether1 list=WAN
add interface=ether2 list=WAN
add interface=SysConCHR list=LAN
/interface wireguard peers
add allowed-address=0.0.0.0/0 endpoint-address=CHR_PUBLIC_IP endpoint-port=\
    13231 interface=SysConCHR name=toCHR persistent-keepalive=25s public-key=\
    "Yccfcfvgbvfvfcdfcfcdf"
/ip address
add address=192.168.2.1/24 comment=defconf interface=bridge network=\
    192.168.2.0
add address=192.168.3.100/24 comment=Starlink interface=ether2 network=\
    192.168.3.0
add address=192.168.1.100/24 comment="Sky Tlcm" interface=ether1 network=\
    192.168.1.0
add address=172.16.100.2/24 comment="CHR WG" interface=SysConCHR network=\
    172.16.100.0
/ip dhcp-server network
add address=192.168.2.0/24 gateway=192.168.2.1
/ip dns
set allow-remote-requests=yes servers=1.1.1.1,9.9.9.9
/ip dns static
add address=192.168.88.1 comment=defconf name=router.lan type=A
/ip firewall filter
add action=accept chain=input comment=\
    "defconf: accept established,related,untracked" connection-state=\
    established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=\
    invalid
add action=accept chain=input comment="defconf: accept ICMP" protocol=icmp
add action=accept chain=input comment=\
    "defconf: accept to local loopback (for CAPsMAN)" dst-address=127.0.0.1
add action=drop chain=input comment="defconf: drop all not coming from LAN" \
    in-interface-list=!LAN
add action=accept chain=forward comment="defconf: accept in ipsec policy" \
    ipsec-policy=in,ipsec
add action=accept chain=forward comment="defconf: accept out ipsec policy" \
    ipsec-policy=out,ipsec
add action=accept chain=forward comment=\
    "defconf: accept established,related, untracked" connection-state=\
    established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" \
    connection-state=invalid
add action=drop chain=forward comment=\
    "defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat \
    connection-state=new in-interface-list=WAN
add action=accept chain=input dst-port=13231 protocol=udp
/ip firewall nat
add action=masquerade chain=srcnat comment="defconf: masquerade" \
    ipsec-policy=out,none out-interface-list=WAN
/ip firewall service-port
set sip disabled=yes
/ip route
add comment="Monitor external host for ISP1" disabled=no distance=1 \
    dst-address=62.217.126.164/32 gateway=192.168.3.1 pref-src="" \
    routing-table=main scope=10 suppress-hw-offload=no target-scope=10
add comment="Monitor external host for ISP2(LTE)" disabled=no distance=1 \
    dst-address=194.177.210.210/32 gateway=192.168.1.1 pref-src="" \
    routing-table=main scope=10 suppress-hw-offload=no target-scope=10
add check-gateway=ping comment="default route ISP1" disabled=no distance=1 \
    dst-address=0.0.0.0/0 gateway=62.217.126.164 pref-src="" routing-table=\
    main scope=30 suppress-hw-offload=no target-scope=11
add check-gateway=ping comment="backup route ISP2" disabled=no distance=2 \
    dst-address=0.0.0.0/0 gateway=194.177.210.210%ether2 pref-src="" \
    routing-table=main scope=30 suppress-hw-offload=no target-scope=11
add comment="toCHR route" disabled=no distance=1 dst-address=0.0.0.0/0 \
    gateway=172.16.100.1 routing-table=toCHR scope=30 suppress-hw-offload=no \
    target-scope=10
/ip service
set telnet disabled=yes
set ftp disabled=yes
set www disabled=yes
set ssh disabled=yes
set api disabled=yes
set api-ssl disabled=yes
/ipv6 firewall address-list
add address=::/128 comment="defconf: unspecified address" list=bad_ipv6
add address=::1/128 comment="defconf: lo" list=bad_ipv6
add address=fec0::/10 comment="defconf: site-local" list=bad_ipv6
add address=::ffff:0.0.0.0/96 comment="defconf: ipv4-mapped" list=bad_ipv6
add address=::/96 comment="defconf: ipv4 compat" list=bad_ipv6
add address=100::/64 comment="defconf: discard only " list=bad_ipv6
add address=2001:db8::/32 comment="defconf: documentation" list=bad_ipv6
add address=2001:10::/28 comment="defconf: ORCHID" list=bad_ipv6
add address=3ffe::/16 comment="defconf: 6bone" list=bad_ipv6
/ipv6 firewall filter
add action=accept chain=input comment=\
    "defconf: accept established,related,untracked" connection-state=\
    established,related,untracked
add action=drop chain=input comment="defconf: drop invalid" connection-state=\
    invalid
add action=accept chain=input comment="defconf: accept ICMPv6" protocol=\
    icmpv6
add action=accept chain=input comment="defconf: accept UDP traceroute" \
    dst-port=33434-33534 protocol=udp
add action=accept chain=input comment=\
    "defconf: accept DHCPv6-Client prefix delegation." dst-port=546 protocol=\
    udp src-address=fe80::/10
add action=accept chain=input comment="defconf: accept IKE" dst-port=500,4500 \
    protocol=udp
add action=accept chain=input comment="defconf: accept ipsec AH" protocol=\
    ipsec-ah
add action=accept chain=input comment="defconf: accept ipsec ESP" protocol=\
    ipsec-esp
add action=accept chain=input comment=\
    "defconf: accept all that matches ipsec policy" ipsec-policy=in,ipsec
add action=drop chain=input comment=\
    "defconf: drop everything else not coming from LAN" in-interface-list=\
    !LAN
add action=accept chain=forward comment=\
    "defconf: accept established,related,untracked" connection-state=\
    established,related,untracked
add action=drop chain=forward comment="defconf: drop invalid" \
    connection-state=invalid
add action=drop chain=forward comment=\
    "defconf: drop packets with bad src ipv6" src-address-list=bad_ipv6
add action=drop chain=forward comment=\
    "defconf: drop packets with bad dst ipv6" dst-address-list=bad_ipv6
add action=drop chain=forward comment="defconf: rfc4890 drop hop-limit=1" \
    hop-limit=equal:1 protocol=icmpv6
add action=accept chain=forward comment="defconf: accept ICMPv6" protocol=\
    icmpv6
add action=accept chain=forward comment="defconf: accept HIP" protocol=139
add action=accept chain=forward comment="defconf: accept IKE" dst-port=\
    500,4500 protocol=udp
add action=accept chain=forward comment="defconf: accept ipsec AH" protocol=\
    ipsec-ah
add action=accept chain=forward comment="defconf: accept ipsec ESP" protocol=\
    ipsec-esp
add action=accept chain=forward comment=\
    "defconf: accept all that matches ipsec policy" ipsec-policy=in,ipsec
add action=drop chain=forward comment=\
    "defconf: drop everything else not coming from LAN" in-interface-list=\
    !LAN
/routing rule
add action=lookup-only-in-table disabled=no min-prefix=0 src-address=\
    192.168.2.200/32 table=main
add action=lookup-only-in-table disabled=no src-address=192.168.2.200/32 \
    table=toCHR
/system clock
set time-zone-name=America/Chicago
/system identity
set name=CoreRouter01
/system note
set show-at-login=no
/system routerboard settings
set enter-setup-on=delete-key
/tool mac-server
set allowed-interface-list=LAN
/tool mac-server mac-winbox
set allowed-interface-list=LAN

@ haris,

I have set up the pbx with the CHR’s public ip and the nat settings.

you don’t have to. your chr should do the translation for your pbx public ip.

think this way;

  1. road warrior → chr → tunnel to pbx.

  2. chr needs to do src nat to both facing the road warrior (internet)
    and to tunnel facing the pbx. so that the pbx only need to know that chr is the only one requesting any sip sessions. (that will include your pbx web ui)

  3. you need to do policy based routing to drive any sip sessions from pbx ( chr tunnel interface) back to chr. otherwise you will have split routing. (which is your pbx reply session going to the internet - not going back via the tunnel)

  4. hence your pbx will have your chr public ip via nat. and road warrior only need to register via chr public ip

  5. have a try. good luck

The way it was explained to me is that the PBX has some internal mechanism to record and pass on some external IP.
So I think its a PBX setting not a router setting at play here. The PBX has to find out the actual public IP address of the CHR…

The PBX does not have to find it out on its own, the PBX needs to be told. There are mechanisms it could use to find out but they are not implemented on all PBXes.

Well, if you should loud enough from your location it might hear you! :stuck_out_tongue_winking_eye:
What I clearly meant is that the OP has to program the PBX so that its aware of the public IP.