I've roughly followed a scheme described in http://onteria.wordpress.com/2011/05/31/dropping-privileges-using-process-setuid-in-node-js/ whereby I start node as root, then downgrade the user. This way I can listen on 80 without the need for a proxy. Pretty standard stuff. I have an upstart script to manage the process (Ubuntu server).
The upstart script redirects stdout/err to a log file (which gets owned by root). Internally I'm using winston to log to the console and a file (which also gets owned by root).
In my perfect and happy world I would be able to transparently chown the log files (both the redirected stdout/err one and the one winston made) to the downgraded user. I've tried (naively) chowning them when I setuid'ed from inside the node app, which worked but meant that they never got written to again.
How can I achieve this? Is this possible or should I try to live with (at least some) log files owned by root?
Many Thanks!
What I've ended up with is a version of Peter Lyons' solution (I've cut'n'pasted the following from a few places, so it may not actually run; the idea works, though):
var logger = new (winston.Logger)();
logger.add(winston.transports.Console, {
timestamp: true
});
// start server and downgrade user
httpsServer.listen(443, function() {
logger.info('Ready on port 443');
fs.stat(__filename, function(err, stats) {
fs.chownSync('stdouterr.log',stats.uid,stats.gid);
process.setgid(stats.gid);
process.setuid(stats.uid);
logger.add(winston.transports.File, {
filename: 'mylogfile.log',
handleExceptions: true
});
logger.info('downgraded to non-root uid', {"uid":stats.uid});
});
});
When I've successfully bound to port 443, I log to say that. logger
is a winston logger configured with only console output (which gets redirected to the stdouterr.log file by starting node using node app.js >> stdouterr.log 2>&1
). So this log message only appears on stdouterr.log
.
Then I figure the owner of the current file and chown stdouterr.log to be owned by this user. Then I set the gid and uid of the current process (the dropping privileges part).
Then I add in my file logging to the winston logger.
Lastly, I log to say I've downgraded the user. This message appears in both stdouterr.log
and mylogfile.log
.
Not quite as beautiful as I'd hoped (no file logging while the process is running as root) but it means that the log files are easy to secure and manage.