You are not logged in.

#1 2019-12-02 07:03:11

hoWlExat
Member
Registered: 2019-11-15
Posts: 35

[SOLVED] Policy-based routing based on port

I have a working SSH server set up. I would like to be able to have my VPN enabled on that server, but when it's enabled, it modifies the `iptables` rules (and maybe more) to route all outgoing traffic via the VPN. So instead of the SSH outbound packets going back via the route they came, they get sent via the VPN. This makes it impossible to SSH into that server when the VPN is enabled, as any clients won't receive their return packets via the expected channels.

I am very new to all of this networking stuff, but I've been told that setting up policy-based routing for traffic on my SSH port might be able to solve this problem. I've found this seemingly useful example, but it's not specifically for port-based policies, and there's enough that I don't yet understand in that article that I'm not able to act on it. Most other articles I've found seem to be written for networking professionals.

Is anyone able to give me a rundown on the different steps I'll have to take and components I'll be dealing with when setting up policy-based routing for SSH traffic?

Thank you so much!

Last edited by hoWlExat (2023-12-19 03:27:05)

Offline

#2 2023-11-14 04:03:40

luthis
Member
Registered: 2016-02-12
Posts: 8

Re: [SOLVED] Policy-based routing based on port

I had the same issue,

I spent literally hours learning nftables and ulogd, only to do this super easily another way.

  sudo ip route add default via 192.168.19.1 table 10
  sudo ip rule add sport 65500 table 10
  sudo ip route flush cache
  ip rule show

resources I used:

http://linux-ip.net/html/tools-ip-rule.html

Now gotta add this so that it survives a reboot

Offline

#3 2023-11-14 09:25:51

luthis
Member
Registered: 2016-02-12
Posts: 8

Re: [SOLVED] Policy-based routing based on port

Ok so to be concise for you users of the future,

# add a default route to some table, arbitrarily table 10 but you can use whatever number (RTFM)
  sudo ip route add default via 192.168.19.1 table 10
# add a rule for the return traffic from your ssh host (I changed my ssh port to this port, so my remote client is expecting traffic back on this port, you probably want to set port 22)
  sudo ip rule add sport 65500 table 10
# self explanatory
  sudo ip route flush cache
#check out your fancy new rule
  ip rule show

And to make this persistent across reboots, add to:

/etc/systemd/network/20-wired.network

(or whatever your file there is, add the following to the bottom)

[Route]
Gateway=192.168.19.1
Table=10

[RoutingPolicyRule]
SourcePort=65500
Table=10

Offline

#4 2023-12-13 08:14:45

hoWlExat
Member
Registered: 2019-11-15
Posts: 35

Re: [SOLVED] Policy-based routing based on port

Thank you for the replies. Unfortunately, I have not managed to get it to work, yet.

For an example, let's say my SSH server has an IP of 192.168.1.2 and is listening on port 100.
I tried following your examples, replacing `via 192.168.19.1` with `via 192.168.1.2`, and replacing `sport 65500` with `sport 100`.
I also tried all sorts of combinations of sport and dport, using 100 and 22.

Still no luck when I have turned on the VPN on the SSH server.
Any further ideas? Thanks

Offline

#5 2023-12-14 05:47:48

-thc
Member
Registered: 2017-03-15
Posts: 503

Re: [SOLVED] Policy-based routing based on port

Before turning on the VPN on your SSH server it uses a default gateway (the local router).

In "luthis" example "192.168.19.1" is the address of that gateway - not the IP address of your server.

Offline

#6 2023-12-19 03:25:27

hoWlExat
Member
Registered: 2019-11-15
Posts: 35

Re: [SOLVED] Policy-based routing based on port

Wow, thank you both so much for the help! This solved it.
So to be clear, I ran the commands:

[user@mylaptop]# sudo su -
[root@mylaptop]# ip route add default via <my-router-ip> table <my-random-int-choice>
[root@mylaptop]# ip rule add sport <the-port-used-for-ssh> table <my-random-int-choice>
[root@mylaptop]# ip route flush cache
[root@mylaptop]# ip rule show
[root@mylaptop]# ip route show table <my-random-int-choice>

Now, I can have my SSH server connected to a VPN and I can successfully SSH into that server from my laptop.
Thank you! big_smile

Offline

#7 2023-12-19 07:54:54

hoWlExat
Member
Registered: 2019-11-15
Posts: 35

Re: [SOLVED] Policy-based routing based on port

To persist the settings, I ended up making a custom systemd service that just executes a script once the network-online.target is hit. Only two lines were needed in that script:

#!/bin/bash
ip route add default via <my-router-ip> table <my-random-int-choice>
ip rule add sport <the-port-used-for-ssh> table <my-random-int-choice>

Last edited by hoWlExat (2023-12-19 07:55:27)

Offline

#8 2024-04-28 14:48:52

kenr101
Member
Registered: 2024-04-28
Posts: 1

Re: [SOLVED] Policy-based routing based on port

luthis wrote:

I had the same issue,

I spent literally hours learning nftables and ulogd, only to do this super easily another way.

  sudo ip route add default via 192.168.19.1 table 10
  sudo ip rule add sport 65500 table 10
  sudo ip route flush cache
  ip rule show

resources I used:

http://linux-ip.net/html/tools-ip-rule.html

Now gotta add this so that it survives a reboot


Hello @luthis,

I have spent hours on this as well but I still have a problem. I have an Apache server listening on TCP port 10001. I have done exactly what you have indicated in your post. From all the reading I've done this should work but for some reason it still does not work for me. I can see the incoming traffic from the Internet being routed to my server's IP but the Apache daemon never sees it. I know this because there is nothing in the access.log. When I disable the VPN client on my server, it works perfectly.

Do you have any tips for troubleshooting this?

Thanks in advance!
K

Gateway: 192.168.2.1
Server: 192.168.2.200

root@ubuntu:~# sudo ip route add default via 192.168.2.1 table 10
root@ubuntu:~# sudo ip rule add sport 10001 table 10
root@ubuntu:~# sudo ip route flush cache
root@ubuntu:~# ip rule show
0:      from all lookup local
32765:  from all sport 10001 lookup 10
32766:  from all lookup main
32767:  from all lookup default

root@ubuntu:~# sudo tcpdump -vv -i enp4s0 dst port 10001
tcpdump: listening on enp4s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
11:34:26.499349 IP (tos 0x28, ttl 42, id 47576, offset 0, flags [DF], proto TCP (6), length 60)
    xxx.xxx.xxx.xxx.38649 > 192.168.2.200.10001: Flags [S], cksum 0x3adb (correct), seq 409521487, win 65535, options [mss 1400,sackOK,TS val 1818389876 ecr 0,nop,wscale 9], length 0
11:34:26.669428 IP (tos 0x28, ttl 42, id 49085, offset 0, flags [DF], proto TCP (6), length 60)
    xxx.xxx.xxx.xxx.38647 > 192.168.2.200.10001: Flags [S], cksum 0x4ad1 (correct), seq 4246722525, win 65535, options [mss 1400,sackOK,TS val 1818390074 ecr 0,nop,wscale 9], length 0
11:34:26.836582 IP (tos 0x28, ttl 42, id 41053, offset 0, flags [DF], proto TCP (6), length 60)

Offline

Board footer

Powered by FluxBB