从express请求对象获取客户端MAC地址

Get client MAC address from express request object

本文关键字:客户端 MAC 地址 获取 对象 express 请求      更新时间:2023-09-26

我正试图从传入的请求对象中获取MAC地址。我的应用程序运行在nginx代理之后,所以为了获得IP地址,我使用以下语法,它运行得很好。

var ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;

同样,还有一种方法可以获得已发出请求的MAC地址。偶然发现这个包裹https://www.npmjs.com/package/getmac我不确定这是否有帮助。从根本上讲,我需要获取每个传入请求的MAC和IP地址。

这是不可能的。MAC地址不通过互联网传输。

请参阅:https://superuser.com/questions/510920/is-my-mac-address-public-when-browsing-the-internet或https://security.stackexchange.com/questions/36583/can-a-website-still-detect-my-real-mac-address-even-if-i-use-different-virtual-m

getmac只会给您服务器网络接口的MAC。)

您不能从请求中获取它,但您可以先获取它,然后将它存储在req.session中。

如何获取mac地址:

const os = require( 'os' );
var mac_ip = os.networkInterfaces()['en3'][3]['mac'];
console.log('ip_test: ', ip_test);
req.session.macip = mac_ip;

您也可以登录networkInterfaces来检查您想要的一切:

var networkInterfaces = os.networkInterfaces();
console.log( networkInterfaces );

注意:此方法将只获取运行节点进程的设备的MAC。如果从服务器运行,此方法将获得服务器的MAC地址,而不是发出请求的客户端的MAC地址。

这对于最初的问题来说太具体了,但其他人可能会觉得这很有用。根据其他答案,这不会在所有条件下都起作用,但确实在下面详述的条件下起作用

我的用例

  • 仅限本地网络服务器
  • Linux计算机

我的解决方案

我之前写过一个脚本,寻找一台已知在网络上并通过其mac地址已知的特定计算机。

homeip=$(sudo arp-scan -lq | grep -i -m 1 $homemac | grep -oP "'d+'.'d+'.'d+'.'d+")

但是,这样做需要很长时间(在具有子网255.255.192.0的网络上这样做可能需要>30s!)

该脚本缓存了ip,并可以使用类似的东西快速验证机器的有效性

ping -c 1 -w 2 -q $homeip > /dev/null
$(arp -a | grep -m 1 -oP "(?<='($homeip') at )(['da-f]{2}:){5}['da-f]{2}") != "$homemac"

因此,我决定为我的服务器,作为一种可能粗糙的身份验证形式,我将按MAC地址将某些用户列入白名单。这样做是多部分

resolveip

#!/bin/bash
out=$(arp -a | grep -m 1 -oP "(?<='($1') at )(['da-f]{2}:){5}['da-f]{2}")
if [ -z "$out" ]; then
    ping -c 1 -w 1 $1 > /dev/null
    echo $(arp -a | grep -m 1 -oP "(?<='($1') at )(['da-f]{2}:){5}['da-f]{2}")
else
    echo $out
fi

创建包装

function getRequestingMAC(requestingIP) {
    return new Promise((resolve, reject) => {
        execFile(`resolveip`, [requestingIP], (error, stdout, stderr) => {
            resolve(stdout.toString().trim());
        });
    });
    // Sync-style
    // return execFileSync(`resolveip`, [requestingIP]).toString().trim();
}

并以此方式使用:

app.use((req, res, next) => {
    if (req.hostname === "localhost") {
    } else {
        //match first occurrence of ipv4 ip, not ideal regex
        let ip = (req.headers['x-forwarded-for'] || req.socket.remoteAddress).match(/'d{1,3}('.'d{1,3}){3}/)[0];
        console.log(ip);
        loop: {
            // check if request came from known ip (my ip)
            const ifaces = require('os').networkInterfaces();
            for (const ifaceKey in ifaces) {
                let iface = ifaces[ifaceKey];
                if (iface.some(it => it.address === ip)) {
                    console.log("Local Request");
                    break loop;
                }
            }
            // else, request mac
            getRequestingMAC(ip).then((ans) => {
                console.log("Request Came From", ans, ip);
                // Give me a banner notif when access attempted
                exec(`zenity --notification --text "Foreign request'n${ans} (${ip}) to ${req.url}"`);
            });
        }
    }
    next();
})

这可以更改为在调用next()之前等待mac,并阻止非白名单请求。

备注

重申一下,这在op的用例中不起作用,但可以在我的用例中也起作用。