PF Bare minimum to block everything and forward web to service running on *:8080?

Hi everyone!

What would be the bare minimum pf.conf I would need to block everything and forward any web requests on port 80 to a service running on *:8080?

I've had a hunt through the forum but there doesn't seem to be an answer I can get working on my machine.
 
Something like this?
Code:
int_if="em0"

rdr on $int_if from any to any port 80 -> 127.0.0.1 port 8080

block in on $inf_if all
pass in on $int_if from any to 127.0.0.1 port 8080
 
Something like this?
...

Hmm... pf is not happy with that! (after typo fix)

Code:
/etc/pf.conf:3: dst port only applies to tcp/udp
/etc/pf.conf:3: rpool port only applies to tcp/udp
/etc/pf.conf:3: skipping rule due to errors
/etc/pf.conf:3: rule expands to no valid combination
/etc/pf.conf:6: port only applies to tcp/udp
/etc/pf.conf:6: skipping rule due to errors
/etc/pf.conf:6: rule expands to no valid combination
pfctl: Syntax error in config file: pf rules not loaded

If it helps, I'm running FreeBSD 11.2-RELEASE-p9
 
Code:
rdr on $int_if proto { tcp, udp } from any to any port 80 -> 127.0.0.1 port 8080

block in on $inf_if all
pass in on $int_if proto { tcp, udp } from any to 127.0.0.1 port 8080

Is that any better? The error points to specific protocols and none were specified.

That's how I have it in mine but I don't use redirection.
 
Thanks, but nope; I still can't seem to serve requests on 80 with responses from 8080.

It's definitely serving:
Code:
$ sockstat -l|grep 80
freebsd  beam.smp   40767 14 tcp4   *:8080
...
...and if I open 8080 to traffic via pf it serves responses fine. I just can't seem to get them on port 80. 😞
 
Bind your proxy server to lo0 or 127.0.0.1. You can only translate traffic that passes an interface and goes out on another. Redirecting from one port to another port on the same interface does not work.
 
Code:
$ sockstat -l|grep 80
freebsd  beam.smp   73494 14 tcp4   127.0.0.1:8080        *:*

Unfortunately this also doesn't seem to work. Testing locally on the machine with lynx does render the page when visiting 127.0.0.1:8080, but visiting the external ip on port 80 fails.
 
Heh, you may be right SirDice, so I'll try to provide some background.

I have a web service (Erlang) which I'd like to make this accessible on port 80. I've tried binding directly to port 80 but since it's a privileged port, that fails. On investigation, various people recommend forwarding requests from port 80 to an unprivileged port. So, I'm running the service bound on *:8080 (and later 127.0.0.1:8080) and I'm attempting to forward web requests to that port and to lock down everything else so the server is secure.

This led to the original question — What would be the bare minimum pf.conf I would need to block everything and forward any web requests on port 80 to a service running on *:8080? — so that I can make my web service accessible to the world while locking everything else down, and then I can build upon that initial ruleset where necessary.
 
See, there's a much better solution for this. You're better off configuring Apache or nginx and proxy it to localhost. That's typically the way these things are set up.

Simplest nginx.conf (not complete, not tested, might contain syntax errors):
Code:
server {
  listen 80;

  location / { 
    proxy_pass http://localhost:8080;
  }
}

Bind your service to localhost only, so it's never directly accessible. Then your firewall only needs to pass traffic to port 80 and can block everything else. No need for complicated redirections or NAT either. Besides that, nginx or Apache are much better at handling large amounts of connections than the applications they typically proxy for.
 
Thanks SirDice, I had considered proxying via Nginx but had to rule it out – it's an additional complication and in my case may cause my web service to slow down; it's an Erlang service that gets a fair number of req/s. Also, wouldn't Nginx fall under the same privilege issue when trying to bind to port 80?

I'd prefer to have the Erlang service serving requests directly. If it's not possible to forward reqs on 80 to 8080, is it possible to allow my service to bind directly to port 80 while maintaining security?
 
I had considered proxying via Nginx but had to rule it out – it's an additional complication and in my case may cause my web service to slow down;
It won't. Not unless you're already pushing it to its limits. But then you shouldn't be running the application on that same host either.

it's an Erlang service that gets a fair number of req/s.
If you're already pushing it you should look into load-balancing solutions like net/haproxy for example. Besides that, the Erlang webserver isn't designed for this, it's a fairly basic webserver. Good enough for development testing and small scale deployment. It's not meant to handle massive amounts of requests.

Also, wouldn't Nginx fall under the same privilege issue when trying to bind to port 80?
No, it's started as root but drops its privileges to a restricted user account once the port has been opened.
 
Thanks for that, I'll get started on the Nginx set-up.

However, I'd still like to try to get an answer to the original question; I've yet to find a working example of forwarding port 80 to another service bound to a different port on localhost, and even though I'm going down the Nginx route now, it may be useful for others coming across this forum page to have a working example to build from. I have a little time to spare to test and confirm a working approach before my service needs to go "live". :)
 
Back
Top