facebook廣告





123

2017年1月29日 星期日

變更Node.js執行的user身份 → Node.js To Lower Privilege

變更Node.js執行的user身份 → Node.js To Lower Privilege


http://blog.xuite.net/zack_pan/blog/72322002-%E8%AE%8A%E6%9B%B4Node.js%E5%9F%B7%E8%A1%8C%E7%9A%84user%E8%BA%AB%E4%BB%BD+%E2%86%92+Node.js+To+Lower+Privilege
大家都知道HTTP是default 80 port,
但只有root執行的程式,才可以bind 0 ~ 1024的port。

可是反過來說,如果每支要用到這些port的程式都用root,
又root可以對系統做任何的事,如果這些程式有"禾斗禾斗"的code,
你的OS可能就一起"禾斗禾斗"了~ XD
所以適當地更改執行的user、降權限是必要的。

不過這又與一開始的敘述矛盾啦!!!
不是root user怎麼bind 80 port!(翻桌

這時候就會有人想到Apache HTTP Server它又是如何達到上述兩個條件的呢?
看了systemd service(我用Archlinux)的設定檔,嗯... 沒有看到有關使用者的指定
後來想想,Apache HTTP Server指定user的地方是http.conf。
也就是說,是daemon自己更改執行的的user!!!(咦

那Node.js又要如何更改執行的user呢?於是乎,有請Google大神
果然,在官網果然有相關的document:process.setuid(id)

稍微整理一下流程:
  1. 由root執行Node.js HTTP Server程式 → HTTP daemon bind 80 port
  2. Node.js HTTP Server程式更改自己的執行user and group為http

以下是Example Code server.js:
/* Just have a web server linstening on 80 port. */
var http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
    console.log('One user request!');
}).listen(80);

/* Set & get user & group id. */
if (process.getuid && process.setuid) {
    console.log('Current uid: ' + process.getuid());
    console.log('Current gid: ' + process.getgid());
    console.log('This process is pid: ' + process.pid);
    try {
        /* Change group to http. */
        process.setgid("http");
        console.log('New gid: ' + process.getgid());
        /* Change user to http. */
        process.setuid("http");
        console.log('New uid: ' + process.getuid());
    }
    catch (err) {
        console.log('Failed to set uid: ' + err);
    }
}
用root身份執行node,而code是server.js。從執行的結果可以看到PID 1186一開始的user和group都是root,bind 80 port之後,user和group就改成http(UID & GID都是33)了。Client連進HTTP服務,可以Server有相對應的console log,以及Client有GET正常的Response。

可以從 top 來看PID和User,如下圖可以確認PID 1186執行的身份是http
sudo netstat -antp | head -n 3  可以看到PID 1186的node listening on 80 port。

沒有留言:

張貼留言