[lug] firewall trickery

David L. Anselmi anselmi at anselmi.us
Tue Jan 31 16:47:03 MST 2006

Daniel Webb wrote:
> Well, I realize the advanced routing list might be a better place for this,
> but I'm not a subscriber, so:
> Suppose I am port forwarding a bunch of ports to the SSH port using
> iptables mangle PREROUTING.  This is done so that each port can be
> assigned to a different user, and each user can then have a different
> qdisc class for the purposes of bandwidth allocation.
> Now I have a problem: how can I prevent users from using other users'
> ports since all the ports just forward to ssh?

How about run a separate sshd (on its own port) for each user and use 
AllowUser to control access?  sshd is where you know for sure who the 
user is.  You can get rid of NAT entirely.  The overhead of extra 
processes should be minimal.

You only need one config file.  The script that starts all the daemons 
can put the port and AllowUser on the command line for each sshd 
(perhaps read from a user-port file or database connection).

> There are two ways I have thought of, and I don't really know if either
> is feasible:
> 1) Can userspace applications see the fwmark set by iptables?  If so, I
> could patch openssh to check that a fwmark is correct during connection
> establishment.

I think you can have whole packets passed to user space and an app could 
inspect them, but I don't think iptables can add data for sshd.  sshd 
just sees a stream of bytes (which won't decrypt if iptables mangles 
it).  Look at the docs on the ip_queue module.

> 2) Set a fwmark based on PID owner match in the OUTPUT table,
> then do something with that.

That means that you're running sshd on the same machine doing the iptables.

> Here's where I'm over my head again.
> The trickiness is due to the way packets traverse the kernel.  PID owner
> match only works on outgoing packets (obviously), but the port of the
> outgoing packet isn't un-NATed until *after* the mangle POSTROUTING
> table.

So you're assuming only the OUTPUT table knows about PID and only the 
POSTROUTING table knows the port the client is connecting to.  But I 
don't think you have a POSTROUTING rule--you're doing DNAT which is 
PREROUTING and the outgoing packets are fixed up by connection tracking. 
  So probably you'd have to write an extension (like the FTP conntrack 
and NAT modules).  That might not be that hard, I don't know.


More information about the LUG mailing list