變更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
以下是Example Code server.js:
可以從 top 來看PID和User,如下圖可以確認PID 1186執行的身份是http。
大家都知道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)
稍微整理一下流程:
但只有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)
稍微整理一下流程:
- 由root執行Node.js HTTP Server程式 → HTTP daemon bind 80 port
- 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);
}
}
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。
沒有留言:
張貼留言