Connecting to Torrent client over LAN

Hi there, just purchased my first MikroTik router hAP ax3, and struggling to connect to my download client over LAN.

First things first, router config (mostly default, but I have been investigating/messing around with this issue for a while now).

# 2025-01-20 14:59:54 by RouterOS 7.17
# software id = xxxxxxx
#
# model = C53UiG+5HPaxD2HPaxD
# serial number = xxxxxx
/interface bridge
add admin-mac=F4:1E:57:4F:27:D9 auto-mac=no comment=defconf name=bridge
/interface wifi
set [ find default-name=wifi1 ] channel.skip-dfs-channels=10min-cac \
    configuration.mode=ap .ssid=xxxxxxx disabled=no \
    security.authentication-types=wpa2-psk,wpa3-psk .ft=yes .ft-over-ds=yes
set [ find default-name=wifi2 ] channel.skip-dfs-channels=10min-cac \
    configuration.mode=ap .ssid=xxxxxxx disabled=no \
    security.authentication-types=wpa2-psk,wpa3-psk .ft=yes .ft-over-ds=yes
/interface list
add comment=defconf name=WAN
add comment=defconf name=LAN
/ip pool
add name=dhcp ranges=10.0.0.70-10.0.0.254
/ip dhcp-server
add address-pool=dhcp interface=bridge name=defconf
/disk settings
set auto-media-interface=bridge auto-media-sharing=yes auto-smb-sharing=yes
/interface bridge port
add bridge=bridge comment=defconf interface=ether2
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=wifi1
add bridge=bridge comment=defconf interface=wifi2
/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
/ip address
add address=10.0.0.1/24 comment=defconf interface=bridge network=10.0.0.0
/ip dhcp-client
add comment=defconf interface=ether1
/ip dhcp-server network
add address=10.0.0.0/24 comment=defconf dns-server=10.0.0.1 gateway=10.0.0.1 \
    netmask=24
/ip dns
set allow-remote-requests=yes
/ip dns static
add address=10.0.0.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="plz qbittorrent" dst-port=8081 \
    protocol=tcp
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=fasttrack-connection chain=forward comment="defconf: fasttrack" \
    connection-state=established,related hw-offload=yes
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 comment="defconf: masquerade" \
    ipsec-policy=out,none out-interface-list=WAN
/ip upnp interfaces
add interface=bridge type=internal
add interface=ether1 type=external
/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
/system clock
set time-zone-name=America/Toronto
/system note
set show-at-login=no
/system routerboard mode-button
set enabled=yes on-event=dark-mode
/system routerboard wps-button
set enabled=yes on-event=wps-accept
/system script
add comment=defconf dont-require-permissions=no name=dark-mode owner=*sys \
    policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    source="\r\
    \n   :if ([system leds settings get all-leds-off] = \"never\") do={\r\
    \n     /system leds settings set all-leds-off=immediate \r\
    \n   } else={\r\
    \n     /system leds settings set all-leds-off=never \r\
    \n   }\r\
    \n "
add comment=defconf dont-require-permissions=no name=wps-accept owner=*sys \
    policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
    source="\r\
    \n   :foreach iface in=[/interface/wifi find where (configuration.mode=\"a\
    p\" && disabled=no)] do={\r\
    \n     /interface/wifi wps-push-button \$iface;}\r\
    \n "
/tool mac-server
set allowed-interface-list=LAN
/tool mac-server mac-winbox
set allowed-interface-list=LAN
/tool sniffer
set file-name="filtered port test" filter-interface=ether2 \
    filter-ip-protocol=tcp filter-port=8081 streaming-enabled=yes \
    streaming-server=10.0.0.253

Background on my setup. I have a RaspberryPi that acts as a home server with individual applications running in separate docker containers. If an application needs to be accessed via the UI, I have the ports exposed through docker and the Pi. My download client is a bit more nuanced as it runs its network traffic through another container running a Wireguard tunnel to a Mullvad VPN server. However, it still exposes a local port and should in theory be accessible. Also, this configuration has worked for other routers.

Here are all the listening ports from the Pi

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      956/sshd: /usr/sbin 
tcp        0      0 0.0.0.0:8989            0.0.0.0:*               LISTEN      314709/docker-proxy 
tcp        0      0 xxxx:52246    0.0.0.0:*               LISTEN      312688/tailscaled   
tcp        0      0 0.0.0.0:9696            0.0.0.0:*               LISTEN      315622/docker-proxy 
tcp        0      0 xxxx:631           0.0.0.0:*               LISTEN      359748/cupsd        
tcp        0      0 0.0.0.0:6969            0.0.0.0:*               LISTEN      381642/docker-proxy 
tcp        0      0 0.0.0.0:7878            0.0.0.0:*               LISTEN      315165/docker-proxy 
tcp        0      0 0.0.0.0:8096            0.0.0.0:*               LISTEN      312620/jellyfin     
tcp6       0      0 :::22                   :::*                    LISTEN      956/sshd: /usr/sbin 
tcp6       0      0 ::1:631                 :::*                    LISTEN      359748/cupsd        
tcp6       0      0 :::8989                 :::*                    LISTEN      314716/docker-proxy 
tcp6       0      0 :::9696                 :::*                    LISTEN      315630/docker-proxy 
tcp6       0      0 xxxx::d:64388 :::*                    LISTEN      312688/tailscaled   
tcp6       0      0 :::6969                 :::*                    LISTEN      381651/docker-proxy 
tcp6       0      0 :::7878                 :::*                    LISTEN      315173/docker-proxy

Also, important to note that I can access ports 7878,9696, and 8989 from my laptop on the LAN.

I have internet access from the Pi itself to the vpn for both the torrent and the vpn tunnel

$ docker exec wireguard curl -s https://am.i.mullvad.net/connected
You are connected to Mullvad (server us-dal-wg-002). Your IP address is 146.70.211.50
$ docker exec qbittorrent curl -s https://am.i.mullvad.net/connected
You are connected to Mullvad (server us-dal-wg-002). Your IP address is 146.70.211.50

The wireguard config tunnel contains some Post Up rules taken from this blog https://www.linuxserver.io/blog/routing-docker-host-and-container-traffic-through-wireguard. These could be causing some of the issue, but I’m really not sure how to diagnose that.

PostUp = DROUTE=10.0.0.1; HOMENET=192.168.0.0/16; HOMENET2=10.0.0.0/8; HOMENET3=172.16.0.0/12; ip route add $HOMENET3 via $DROUTE;ip route add $HOMENET2 via $DROUTE; ip route add $HOMENET via $DROUTE;iptables -I OUTPUT -d $HOMENET -j ACCEPT;iptables -A OUTPUT -d $HOMENET2 -j ACCEPT; iptables -A OUTPUT -d $HOMENET3 -j ACCEPT;  iptables -A OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
PreDown = HOMENET=192.168.0.0/16; HOMENET2=10.0.0.0/8; HOMENET3=172.16.0.0/12; ip route delete $HOMENET; ip route delete $HOMENET2; ip route delete $HOMENET3; iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT; iptables -D OUTPUT -d $HOMENET -j ACCEPT; iptables -D OUTPUT -d $HOMENET2 -j ACCEPT; iptables -D OUTPUT -d $HOMENET3 -j ACCEPT

Finally, I ran nmap from the computer I’m trying to use the UI on and keep getting that the port I want is filtered. It does seem strange that the open ports that work aren’t registered by nmap, but I’m not too worried about that.

~% nmap 10.0.0.69 -sV
Starting Nmap 7.95 ( https://nmap.org ) at 2025-01-20 13:21 MST
Nmap scan report for 10.0.0.69
Host is up (0.033s latency).
Not shown: 998 closed tcp ports (conn-refused)
PORT     STATE    SERVICE VERSION
22/tcp   open     ssh     OpenSSH 9.2p1 Debian 2+deb12u2 (protocol 2.0)
6969/tcp filtered acmsoda
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

I’m truly stumped, and pretty new to networking so any help at all would be extremely helpful. Thanks in advance!

Figured it might be useful to post the firewall rules of the Raspberry Pi server

$ sudo iptables -L
# Warning: iptables-legacy tables present, use iptables-legacy to see them
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy DROP)
target     prot opt source               destination         
DOCKER-USER  all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-1  all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain DOCKER (5 references)
target     prot opt source               destination         
ACCEPT     tcp  --  anywhere             172.31.0.2           tcp dpt:8989
ACCEPT     tcp  --  anywhere             172.20.0.2           tcp dpt:7878
ACCEPT     tcp  --  anywhere             172.19.0.2           tcp dpt:9696
ACCEPT     tcp  --  anywhere             172.18.0.2           tcp dpt:6969

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination         
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            

Chain DOCKER-ISOLATION-STAGE-2 (5 references)
target     prot opt source               destination         
DROP       all  --  anywhere             anywhere            
DROP       all  --  anywhere             anywhere            
DROP       all  --  anywhere             anywhere            
DROP       all  --  anywhere             anywhere            
DROP       all  --  anywhere             anywhere            
RETURN     all  --  anywhere             anywhere            

Chain DOCKER-USER (1 references)
target     prot opt source               destination         
RETURN     all  --  anywhere             anywhere

They seem permissive to me with the required open ports, but I am still new to this so I could be interpreting it incorrectly.