# [Solved] Mark outgoing packets based on application

## Saundersx

Here's what I'm currently doing

I'm running xbmc on my pvr/router/etc. I have a vpn that uses an US ip address so I can get on those "us-only" video sites in xbmc's video addons. I keep it connected to the vpn all the time and have shorewall set up to only forward certain destination ips through the vpn. 

As it stands everything works pretty good. Hulu works and a handful of other sites work for the most part.

What I want to do

I want to simply mark all packets from xbmc so shorewall can forward them through the vpn. While what I'm doing now works it is an endless pita keeping an ongoing list of ips that need to be forwarded. Some urls forward to multiple addresses so I have to then lock them down to one in the hosts file etc etc. 

The functionality to do this was removed from iptables some time ago and has not returned. So my question is - is there any other method to accomplish this? I don't care how hacky or if I have to run some wrapper script/daemon/sniffer or what. Just can it be done anymore?Last edited by Saundersx on Thu Oct 13, 2011 5:07 am; edited 1 time in total

----------

## Bones McCracker

You could probably set the application to run SGID some dedicated group (e.g. "xbmc") and then use the iptables "owner" match to mark the outbound packets for routing.

How were you doing it before?

----------

## Hu

If you can force xbmc to bind to a specific address before calling connect, you could use policy-based routing to ensure that connections from that address are sent over the VPN.

----------

## Bones McCracker

 *Hu wrote:*   

> If you can force xbmc to bind to a specific address before calling connect, you could use policy-based routing to ensure that connections from that address are sent over the VPN.

 

Yes.  A virtual network interface would work too.

----------

## Saundersx

 *Hu wrote:*   

> If you can force xbmc to bind to a specific address before calling connect, you could use policy-based routing to ensure that connections from that address are sent over the VPN.

 

I know xbmc itself cannot do that, how would I accomplish this?

----------

## Hu

If xbmc does not support binding before connect, then you either need to patch it to add that support or use one of the other suggestions in the thread.  To be fair, not many applications need support for an explicit bind, so it is not unusual if xbmc lacks this feature.

----------

## Bones McCracker

Check the documentation.

Using sgid and the "owner" match is still an alternative if you can't control what it binds to.

Yet another possibility would be to run it in a linux container (LxC) or virtual machine.  This would give it a unique network interface, and it might also enhance the security of your setup.  If you're not familiar with these things, this approach will probably make your project too complicated.

----------

## Saundersx

Just wanted to add that using the sgid and some shorewall hackery did the trick, everything works 100%.

----------

## Bones McCracker

Good.

What shorewall hackery was required (for others to refer to if searching)?

----------

## Saundersx

Just to be clear this may not be the CORRECT way of doing this, but it does work.

Firstly I compile the svn/git version of xbmc. So I have a script I run to do this.

```
FEATURES="distcc ccache" emerge -av xbmc

echo 'setting xbmc permissions'

chown root:xbmc /usr/bin/xbmc /usr/lib64/xbmc/xbmc.bin

chmod g+s /usr/bin/xbmc /usr/lib64/xbmc/xbmc.bin
```

Yes I run as root, no I don't care to hear about it. The rest are snippits from shorewall which only apply to the vpn.

shorewall/params

```

# my internal network

INTERNAL=192.168.0.0/16

# interfaces (eth0 = internet, eth1 = internal network (two port motherboard, eth1 goes to a switch which feeds rest of house)

INET_IF=eth0

ROUTER_IF=eth1

VPN_IF=tun0
```

shorewall/interfaces

```
#ZONE   INTERFACE       BROADCAST       OPTIONS

net     $INET_IF        detect          dhcp

loc     $ROUTER_IF      detect          dhcp,sourceroute

net     $VPN_IF         -               optional
```

shorewall/masq

```
#INTERFACE              SOURCE          ADDRESS         PROTO   PORT(S) IPSEC   MARK    USER/

#                                                                                       GROUP

# VPN (note the MARK = 2)

$VPN_IF                 -               detect          -       -       -       2

# any computers internally not connecting to other computers internally are masq'd to the internet

$INET_IF:!$INTERNAL     $ROUTER_IF
```

shorewall/providers

```
#NAME   NUMBER  MARK    DUPLICATE       INTERFACE       GATEWAY         OPTIONS         COPY

isp     1       1       main            $INET_IF        detect          balance=1       $ROUTER_IF

myvpn   2       2       main            $VPN_IF         detect          balance=2,loose $ROUTER_IF
```

shorewall/route_rules

```
#SOURCE                 DEST                    PROVIDER        PRIORITY

lo                      -                       isp             11000

eth1                    -                       isp             11000
```

shorewall/rules

```
#ACTION         SOURCE          DEST            PROTO   DEST    SOURCE          ORIGINAL        RATE               USER/   MARK    CONNLIMIT       TIME

#                                                       PORT    PORT(S)         DEST            LIMIT              GROUP

#SECTION ESTABLISHED

#SECTION RELATED

SECTION NEW

# VPN ("myvpn")

ACCEPT          net     fw              udp     1194

ACCEPT          fw      net             udp     1194
```

shorewall/tcrules

```
#MARK   SOURCE          DEST            PROTO   DEST    SOURCE  USER    TEST    LENGTH  TOS   CONNBYTES            HELPER

#                                               PORT(S) PORT(S)

# by default everything goes through the default isp

# these rules are processed in order so matching rules below will override

# these also override "balance=x" in the providers file

1       fw

1:P     0.0.0.0/0

# "xbmc" group only

2       fw              !$INTERNAL      all     -       -       :xbmc

2:T     0.0.0.0/0       !$INTERNAL      all     -       -       :xbmc
```

one thing worth noting is that I didn't setup a "vpn" interface and only the "xbmc" group uses the vpn. 

some caveats: in order to make sure everything works properly run "shorewall restart" after xbmc has started AND the vpn has connected. I also revert back to the original /etc/resolv.conf after the vpn connects. I have a script I wrote to do this but I will not be posting it as it was written to continuously reconnect until it gets a US server from one of those damn shared vpns where you have no control which country your dumped to. I'm sure they would appreciate that getting released...

I have been using shorewall for years and I recommend it highly but I am not an expert in shorewall, this is all poc, I will not help in troubleshooting anything.   :Wink: 

----------

## Bones McCracker

Thanks for sharing it.  Maybe it will save somebody some time, and maybe you'll get suggestions on how to improve it.   :Smile: 

Can you mark "[Solved]", please?  Thanks.

----------

