Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

A word of warning guys, I've had a look through the code and unless I've missed the obvious, there's nothing in there to change user ID; which means this would either need to be run as root, or would need to listen on a port > 1024.

In the case of the former, that's a huge step backwards in terms of security.

In the case of the latter, that would mean you'd need another reverse proxy hooked up - which would negate the need for this web server to begin with.

This can easily be fixed within Go though:

    import (
    	"log"
	"syscall"
    )
    
    const (
    	user_id  int = 1000
    	group_id int = 1000
    )
    
    func secureDaemon() {
    	// set group id first as you need to be root to change group
    	err := syscall.Setgid(group_id)
    	if err != nil {
    		log.Fatalln(err)
    	}
    	
    	err = syscall.Setuid(user_id)
    	if err != nil {
    		log.Fatalln(err)
    	}	
    }
You can also add chroot to your code if you want to be ultra paranoid:

    import (
	"os"
    )
    
    const (
    	chroot_dir string = "/opt/go-webserver"
    )
    
    func chrootDaemon() {
    	err := os.Chdir(chroot_dir)
    	if err != nil {
    		log.Fatalln(err)
    	}

    	err = syscall.Chroot(chroot_dir)
    	if err != nil {
    		log.Fatalln(err)
    	}
    }
This will need to be done before you change your user ID (as you need root permissions to chroot) and you may need to compile the Go without CGO because some of the standard Go libraries will have SO dependencies (I found this to be the case with domain name lookups).

(the above code is adapted from my own Go web framework that I'm in the processes of building)



just implemented -secure option for this purpose; https://github.com/azer/boxcars/blob/master/secure.go

usage example; http://github.com/azer/boxcars#security

thanks for the helpful comment!


Please see my comment to your parent. Additional hint: you should also care about dropping/controlling your user's groups, see https://github.com/sarnowski/mitigation/blob/master/mitigati...


yeah I saw it, thanks so much. I like this kind of single-purpose small libraries. The only thing is, I hesitate to depend on other people's repositories since they may get moved or change the API.


WARNING: I implemented a tiny library for that in go a while ago. Go under Linux is not safe! Linux is not posix compliant and only sets the IDs for the current thread. Go almost always spawned more threads before initializing your code which are then still owned by root and are in the threadpool for your goroutines:

https://github.com/sarnowski/mitigation/blob/master/mitigati...

Comments mentions safe OS and golang bugticket.


I'm guessing it might depend on the point in your Go code whrn you setuid as the tests that I did on my own project, setuid changed the user id as expacted then the processes were spawned.

However you have given me reason to test my own code again and more thoroughly :-)


A program run as a non-privileged user can access privileged ports using authbind:

http://en.wikipedia.org/wiki/Authbind


Indeed, but it would make more sense (in my opinion) to have the web server natively 'de-elevate' it's permissions than to expect the sysadmin to be competent enough to set up authbind manually. Particularly when setuid/setgid is so easy in Go and that every other webserver out there natively drops down to a designated webuser after the daemons been launched and ports binded.


Seems to be GNU/Linux only.


Come in, the water's warm.


authbind seems to defeat the purpose of privileged and non-privileged users to bind.


There's really not much of a purpose to that anymore, anyways. It was a bigger deal when servers were multi-user and when services were diverse.


It's easy enough to run this as a non-root user and use your local software firewall port to forward port 80 inbound to whatever high port this server is listening on.


Indeed, but that doesn't change the fact that it makes more sense having that functionality in the web server itself given its a standard and expected function in all web servers.


thanks! would you mind sending a pull request to https://github.com/azer/boxcars/blob/master/boxcars/boxcars.... ?


I'm not on Github, sorry. But that code should be pretty easy to port to your app :)


Just curious why you aren't on github. Surely there's a reason worth sharing?


I tend not to sign up to many cloud based solutions as I prefer to host my own solutions (partly out of paranoia and partly because I have the server capacity to run my own solutions so it seems to make sense to use my servers where I can).

With github, it's very rare when I have anything worth contributing to other peoples gits so I've never really missed it. But I'm sure I'll end up on there at some point in the future.


Why not send them a patch?


I'm not on github, which is why I made my OP so verbose; all the working code is there, s/he just needs to integrate it into their own code :-)




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: