Created attachment 155368 [details] haproxy port patch Hello, This patch installs a sample config from the EXAMPLES dir already modified to use a new haproxy uid and gid. It also has chroot enabled to the /var/empty directory which should be sufficient. This should help alleviate damage from a future haproxy exploit as haproxy would not be running as root. Unfortunately we cannot just force haproxy to always run as root via the rc script as haproxy may need to listen on reserved ports (<1024) to proxy 80, 443, etc. It would be wise to encourage users in pkg-message to update their configurations to use the haproxy user, but I have not composed such a message.
I am not sure haproxy reserves its own uid/gid? Why not run it as www or nobody?
If you run other processes on your server as nobody/www and someone compromises haproxy they have access to everything under the www or nobody user.
I understand. But there is some common sense also. Do you plan to modify nginx and apache, for instance, so they use different uids? In my opinion, installing a sample config with chroot to /var/empty is OK, but having a separate uid is overkill.
(In reply to Dmitry Sivachenko from comment #3) The paranoid OpenBSD approach would be "absolutely, yes, every daemon gets its own uid/gid." and when you look at the UIDs and GIDs file I'm sure we could distill a lot of that down to sharing the www and nobody uid/gids if we really wanted to... Anyway, it is recommended (and shown in sample configs) to run as non-root and chrooted if possible, so can we at least achieve that so the sample config requires minimal editing for a user to be following best practices?
Well, looking at actual content of examples/haproxy.cfg I do not see how it can be useful as a prototype of real haproxy config for a starter: it contains 80 lines of some example backends containing real IPs with some specific options. The probability for it to be useful prototype is close to zero. It would be necessary to replace 90% of it's content for it to work in some real case. I don't think it is useful to install this file just because it contains chroot, uid and gid parameters. I propose to add some notes about chroot, uid and gid to pkg-message instead to point users to these options.
(In reply to Dmitry Sivachenko from comment #5) Then why does haproxy ship the sample config at all if it's not useful? You could say this about most complex software which provides sample configs. You can't expect it to "work" out of the box because there is no standard deployment, but you can provide them with a sufficient example that they can quickly grasp which changes need to be made and what it is capable of.
There are a lot of different configs in examples/ directory. How did you select this one? Just for filename? Their content look similar.
I just stumbled upon this PR again. Do we agree that we should not be running haproxy as root by default? Thanks
I agree. I use www to run haproxy, nobody suites well too.
(In reply to Dmitry Sivachenko from comment #9) Haproxy appears to only allow setting the user in the config file, so if we want to encourage this behavior by default we might have to supply a sample config.
Well, this is not something FreeBSD-specific. And FreeBSD ports are intended to make a minimal modification of the original program so it can be used on FreeBSD. So the proper solution would be to introduce generic sample config file upstream and the install it on FreeBSD.
This vaulable & simple PR is languishing. - I'd love to see a bundled haproxy dedicated user to minimise accessible data in the event of an attack. There are arguments for & against this, but I think it's common practice to restrict daemons from seeing other daemon's data. - The privileged port bind argument is easily resolved via sysctl net.inet.ip.portrange.reservedhigh=0 which could be a comment in the pkg-message. - If somebody wishes to submit a simpler haproxy configuration upstream then please do so, but it doesn't need to be something that blocks this PR indefinitely
(In reply to Dave Cottlehuber from comment #12) 1) "The privileged port bind argument is easily resolved via sysctl net.inet.ip.portrange.reservedhigh=0" You can't restrict this to act only for haproxy process, other programs could exploit this too. 2) "If somebody wishes to submit a simpler haproxy configuration upstream then please do so, but it doesn't need to be something that blocks this PR indefinitely" What do you suggest to do? Just add haproxy:haproxy user to system? As I wrote before, I think it is overkill. There are several pseudo-users already available for that purpose (do you have both www and nobody already occupied?), and I am not for paranoid OpenBSD's approach. Also, even if we create such a pseudo-user it won't be of much help to real users, because sample config file will not fit for 99.5% of users and you can "user" and "group" directives to your config file without modifying the port. Haproxy can be used for a lot of different purposes requiring a lot of completely different configurations. I see no elegant solution for this now.
(In reply to Dmitry Sivachenko from comment #13) >You can't restrict this to act only for haproxy process, other programs could exploit this too. We have the capability of restricting this to only the haproxy user in FreeBSD. It's part of the MAC framework. It wouldn't hurt to have this better documented. Want haproxy user (uid 992) to listen on port 443? kldload mac_portacl sysctl security.mac.portacl.rules=uid:992:tcp:443
Okay, this is another possibility. But this sounds paranoid: haproxy supports UID change after startup (just like Apache), and it looks like cleaner approach.
Status?
I would also like to know what the status of this is? Are we in 2024 still saying that creating a separate user/group for a daemon is still overkill? When just about every daemon package has its own user these days. I would say it's not overkill. ESPECIALLY not when the example configs use haproxy:haproxy. Because it's the default these days. Are we really, as FreeBSD, going to advocate "it's fine, don't worry about security". Because that seems... wrong?