Project

General

Profile

Actions

Bug #14772

open

PFsense Plus doesn't work with AWS new Instance Metadata Service (IMDSv2)

Added by Cameron Epp 6 months ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
Installer
Target version:
-
Start date:
Due date:
% Done:

0%

Estimated time:
Release Notes:
Default
Affected Plus Version:
23.05.1
Affected Architecture:
amd64

Description

AWS has an updated version of their metadata service (IMDS) that is designed to add some defense-in-depth (see https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service/ for details).

PFsense Plus is using the older IMDSv1 instead of IMDSv2. See https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-add-user-data.html for more details on how to make the call to get userdata using IMDSv2

I think that you could add support for IMDSv2 by updating the retrieveMetaData function in /usr/local/sbin/ec2_setup.php. If you retrieve the token first, you can then use that token to get the requested info. Here is what I think the function should be:

function retrieveMetaData($url) {
    if (!$url)
        return;

    $curl = curl_init();

    /* first get the instance token which we will use to 
        authenticate the subsequent call */

    $token_url = "http://169.254.169.254/latest/api/token";
    $headers = array (
        'X-aws-ec2-metadata-token-ttl-seconds: 10' );
    curl_setopt($curl, CURLOPT_URL, $token_url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers );
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true );
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT" );
    curl_setopt($curl, CURLOPT_FAILONERROR, true);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 15);
    curl_setopt($curl, CURLOPT_TIMEOUT, 30);
    $token = curl_exec($curl);

    /* now build the 'real' request and send it along with the
       token for authentication */

    $headers = array (
        'X-aws-ec2-metadata-token: '.$token );
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers );
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true );
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET" );
    curl_setopt($curl, CURLOPT_FAILONERROR, true);
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 15);
    curl_setopt($curl, CURLOPT_TIMEOUT, 30);
    $metadata = curl_exec($curl);
    curl_close($curl);

    return($metadata);
}

n.b. I haven't taken the time to try and build a fresh ami in AWS, so I may have some syntax wrong!


Files

ec2_setup.php (13.8 KB) ec2_setup.php Suggested update Cameron Epp, 09/11/2023 06:50 PM

No data to display

Actions

Also available in: Atom PDF