Bypass VPN for webserver service

I'm running a home server with FreeBSD 12.1. I have openvpn enabled strictly on the server; the rest of my home network – including router - is non-vpn.

I don't know if it's even feasible, but I'm hoping to have the server do double duty as a VPN server and non-VPN webserver (via lighttpd). My efforts so far have been unsuccessful.

I set up the webserver for port 8080 (my ISP keeps 80 closed), and set my DD-WRT router to forward incoming port 8080 to server 8080 (192.168.1.250).

Testing by means of https://validator.w3.org, the webserver connects externally via my router's external IP (with ":8080" added) only if I stop openvpn. Local machines, however, can access the webserver through the external router address while openvpn is enabled.

The only way I can access the webserver via an outside machine is through the server's VPN IP (178.73.218.69:8080). However, that address always changes when the server or openvpn restarts, so using it regularly is not practical.

The only new ipfw rules I added for my webserver are 00099 and 00100. The other rules are very basic - essentially "kill-switches" for my torrent and NZB traffic if openvpn stops:
Code:
00001 allow ip from any to any via lo0
00010 allow ip from any to any via tun0
00099 allow tcp from any to me 8080 in via em0
00100 allow tcp from me 8080 to any out via em0
00101 allow ip from me to 192.168.1.0/24 uid transmission
00102 allow ip from 192.168.1.0/24 to me uid transmission
00103 deny ip from any to any uid transmission
00104 allow ip from me to 192.168.1.0/24 uid sabnzbd
00105 allow ip from 192.168.1.0/24 to me uid sabnzbd
00106 deny ip from any to any uid sabnzbd
65535 allow ip from any to any
Here's my ifconfig:
Code:
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=81049b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,LRO,VLAN_HWFILTER>
        ether 34:17:eb:d1:30:df
        inet 192.168.1.250 netmask 0xffffff00 broadcast 192.168.1.255
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
        options=680003<RXCSUM,TXCSUM,LINKSTATE,RXCSUM_IPV6,TXCSUM_IPV6>
        inet6 ::1 prefixlen 128
        inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
        inet 127.0.0.1 netmask 0xff000000
        groups: lo
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> metric 0 mtu 1500
        options=80000<LINKSTATE>
        inet6 fe80::3617:ebff:fed1:30df%tun0 prefixlen 64 scopeid 0x3
        inet 178.73.218.69 --> 178.73.218.65 netmask 0xffffffe0
        groups: tun
        nd6 options=21<PERFORMNUD,AUTO_LINKLOCAL>
        Opened by PID 4056
And with openvpn enabled, “netstat -4rn” shows this:
Code:
Destination        Gateway            Flags     Netif Expire
0.0.0.0/1          178.73.218.65      UGS        tun0
default            192.168.1.1        UGS         em0
127.0.0.1          link#2             UH          lo0
128.0.0.0/1        178.73.218.65      UGS        tun0
178.73.195.104/32  192.168.1.1        UGS         em0
178.73.218.64/27   178.73.218.65      UGS        tun0
178.73.218.65      link#3             UH         tun0
178.73.218.69      link#3             UHS         lo0
192.168.1.0/24     link#1             U           em0
192.168.1.250      link#1             UHS         lo0
Are there adjustments that can be made to have this work? Or am I forced to have a separate machine as webserver?
 
I've been unsuccessful w/ jails - too much work and too many variables. I'll keep it simple and just set up a separate machine to work as webserver.
 
I don't see how setting up a complete host is less work than just spin up some jails e.g. with iocell or iocage...

To begin with I'd first put the VPN service inside a jail to keep it from interfering with the host's routing. Give it separate interfaces for egress (where vpn clients will connect to) and the internal network. This will simplify routing (and firewalling) A LOT. Especially because you can strip down the routing table for that jail to a bare minimum.

The webserver could run on it's ow alias IP or just attach the jail to a loopback device and handle all redirection with PF 'rdr' rules (preferably still with a distinct IP, not the hosts IP if it even has any on the same device...). I often use the loopback approach because it keeps the host configuration clean and simplifies upgrades/replacement of jails. just clone them or set up a new one and change the ip of the rdr rule if everything is up and running.
 
I'm sure the suggestions to set up jails is straightforward for a seasoned FreeBSD user (which I am not). However, I have attempted to set up jails several times over the last few years, only to spend hours of frustration culminating in failure, unaided by so-called "help" guides that are anything but.

On the other hand, I set up from scratch a separate host running as a dedicated webserver in only a short amount of time.
 
I set up from scratch a separate host running as a dedicated webserver in only a short amount of time.
Setting this up is no different from setting it up in a jail. For all intents and purposes treat a jail like a separate host.
 
Thanks for the advice about the iptables on my router - I'll look into it.

What amazes me is how laborious it can be to accomplish what should be a straightforward goal:
Have all traffic to/from a single port bypass the VPN.

That's all I want!
 
It's easy to bypass it if you know the source and destination IP then you can use a static route and you are done.
 
Another approach is using, for example, cloudflare.
Knowing their IP range, you can detect which requests are " legit" and can be passed through.
Other requests can just be dropped, so nobody except cloudflare knows you have a webserver running.
 
other option is to use SNAT & MASQUERADE on your dd-wrt iptables and masquarade all request coming from WAN to 8080 to 192.168.1.1 (your router ip) and then forward to your local server at 192.168.1.250 the downside of this is you will be unable to distinguish clients by they ip address on your web server as all requests will appear to came from 192.168.1.1
The iptable setup you describe sounds like my directive under my DD-WRT router's "Port Forwarding" tab: all incoming TCP traffic from WAN port 8080 gets forwarded to port 8080 on webserver (192.168.1.250).

Or is it different?
 
So... I really fail to understand all the problems here and I'm also missing out on some important information. So.. your webserver process is running and should be using port 8080. I'm not familiar with IPFW from mind so I'll just assume that rules 99 and 100 provide access.

First: what does # sockstat -4l tell you about port 8080?

While you did mention clients outside your network you never bothered with those on the network? What happens if they try to access your LAN IP to connect to the webserver?

See, for all I know your webserver isn't listening to 192.168.1.250 which would explain quite a bit of your issues. Seriously, setting this up should be trivial, no issue at all. As long as each process has been properly set up.
 
So... I really fail to understand all the problems here and I'm also missing out on some important information. So.. your webserver process is running and should be using port 8080. I'm not familiar with IPFW from mind so I'll just assume that rules 99 and 100 provide access.

First: what does # sockstat -4l tell you about port 8080?

While you did mention clients outside your network you never bothered with those on the network? What happens if they try to access your LAN IP to connect to the webserver?

See, for all I know your webserver isn't listening to 192.168.1.250 which would explain quite a bit of your issues. Seriously, setting this up should be trivial, no issue at all. As long as each process has been properly set up.

Yes, all local machines can access the webserver pages (with OpenVPN running) via webserver's internal address (192.168.1.250:8080) as well as the router's external address (w/ ":8080" added).

And all external machines can access my webserver (via router address w/ ":8080" added) if OpenVPN isn't running.

Running "sockstat -4l" on my webserver shows port 8080 as I believe it should be:
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS
www lighttpd 80576 5 tcp4 *:8080 *:*

In a previous post, VladiBG provided a link that suggested inserting "--pull-filter ignore redirect-gateway" in my openvpn conf file. However, after doing so, ALL traffic on the machine stopped going through VPN.
 
Back
Top