head	1.8;
access;
symbols
	netbsd-11-0-RC4:1.6
	netbsd-11-0-RC3:1.6
	netbsd-11-0-RC2:1.6
	netbsd-11-0-RC1:1.6
	perseant-exfatfs-base-20250801:1.6
	netbsd-11:1.6.0.4
	netbsd-11-base:1.6
	netbsd-10-1-RELEASE:1.5.2.1
	perseant-exfatfs-base-20240630:1.6
	perseant-exfatfs:1.6.0.2
	perseant-exfatfs-base:1.6
	netbsd-9-4-RELEASE:1.1
	netbsd-10-0-RELEASE:1.5.2.1
	netbsd-10-0-RC6:1.5.2.1
	netbsd-10-0-RC5:1.5.2.1
	netbsd-10-0-RC4:1.5.2.1
	netbsd-10-0-RC3:1.5.2.1
	netbsd-10-0-RC2:1.5.2.1
	netbsd-10-0-RC1:1.5.2.1
	netbsd-10:1.5.0.2
	netbsd-10-base:1.5
	netbsd-9-3-RELEASE:1.1
	cjep_sun2x-base1:1.1
	cjep_sun2x:1.1.0.12
	cjep_sun2x-base:1.1
	cjep_staticlib_x-base1:1.1
	netbsd-9-2-RELEASE:1.1
	cjep_staticlib_x:1.1.0.10
	cjep_staticlib_x-base:1.1
	netbsd-9-1-RELEASE:1.1
	phil-wifi-20200421:1.1
	phil-wifi-20200411:1.1
	is-mlppp:1.1.0.8
	is-mlppp-base:1.1
	phil-wifi-20200406:1.1
	netbsd-9-0-RELEASE:1.1
	netbsd-9-0-RC2:1.1
	netbsd-9-0-RC1:1.1
	phil-wifi-20191119:1.1
	netbsd-9:1.1.0.6
	netbsd-9-base:1.1
	phil-wifi:1.1.0.4
	phil-wifi-20190609:1.1
	pgoyette-compat-merge-20190127:1.1.2.2
	pgoyette-compat-20190127:1.1
	pgoyette-compat-20190118:1.1
	pgoyette-compat:1.1.0.2
	pgoyette-compat-1226:1.1;
locks; strict;
comment	@# @;


1.8
date	2026.05.16.20.59.59;	author jschauma;	state Exp;
branches;
next	1.7;
commitid	QlVrDO22wgQoa5GG;

1.7
date	2026.02.01.22.57.34;	author jschauma;	state Exp;
branches;
next	1.6;
commitid	q5iGkxncyIeU9JsG;

1.6
date	2023.09.27.00.27.07;	author riastradh;	state Exp;
branches;
next	1.5;
commitid	466zxCw426LEglGE;

1.5
date	2022.10.15.18.32.30;	author jmcneill;	state Exp;
branches
	1.5.2.1;
next	1.4;
commitid	8oUkXf39zTEsqQXD;

1.4
date	2021.07.20.19.31.23;	author rhialto;	state Exp;
branches;
next	1.3;
commitid	x8hIupuIfdDOgL1D;

1.3
date	2021.07.15.19.03.17;	author rhialto;	state Exp;
branches;
next	1.2;
commitid	Uh5J1u9Y9dODh71D;

1.2
date	2021.07.01.18.05.45;	author jmcneill;	state Exp;
branches;
next	1.1;
commitid	AblztVgRLChLpjZC;

1.1
date	2018.11.30.20.53.02;	author jmcneill;	state Exp;
branches
	1.1.2.1
	1.1.4.1;
next	;
commitid	Y7xhCRLXw2UwG02B;

1.5.2.1
date	2023.10.02.13.27.41;	author martin;	state Exp;
branches;
next	;
commitid	H0m2Z2vJ5wotq3HE;

1.1.2.1
date	2018.11.30.20.53.02;	author pgoyette;	state dead;
branches;
next	1.1.2.2;
commitid	xUhK8IAeBM1azj5B;

1.1.2.2
date	2018.12.26.14.01.13;	author pgoyette;	state Exp;
branches;
next	;
commitid	xUhK8IAeBM1azj5B;

1.1.4.1
date	2018.11.30.20.53.02;	author christos;	state dead;
branches;
next	1.1.4.2;
commitid	jtc8rnCzWiEEHGqB;

1.1.4.2
date	2019.06.10.21.42.37;	author christos;	state Exp;
branches;
next	;
commitid	jtc8rnCzWiEEHGqB;


desc
@@


1.8
log
@Improve metadata fetching to work more reliably across
IPv4-only, IPv6-only, and dual-stack instances.

AWS does not by default enable the metadata service on
IPv6; you have to specify '--metadata-options "HttpProtocolIpv6=enabled"'.
Without this, even a dual-stack instance can't fetch
metadata from the IPv6 endpoint.

In addition, reaching the metadata service takes some
time, so we can't trivially check for network
readiness and instead need to actually try to fetch a
file.  Ok.

While here, don't overwrite a hostname that is set
from /etc/rc.conf and only set the hostname if
otherwise unset.
@
text
@#!/bin/sh
#
# $NetBSD: ec2_init,v 1.7 2026/02/01 22:57:34 jschauma Exp $
#
# PROVIDE: ec2_init
# REQUIRE: NETWORKING
# BEFORE:  LOGIN

$_rc_subr_loaded . /etc/rc.subr

name="ec2_init"
rcvar=${name}
start_cmd="ec2_init"
stop_cmd=":"

HOSTNAME_URL="hostname"

IMDS_IP="169.254.169.254"
IMDS_IPv6="fd00:ec2::254"

CLOUD_TYPE=EC2
case "$(/sbin/sysctl -n machdep.dmi.chassis-asset-tag 2>/dev/null)" in
OracleCloud*)
	CLOUD_TYPE=OCI
	;;
esac

EC2_USER="ec2-user"
case ${CLOUD_TYPE} in
EC2)
	EC2_USER="ec2-user"
	METADATA_URL_PATH="latest/meta-data/"
	SSH_KEY_URL="public-keys/0/openssh-key"
	;;
OCI)
	EC2_USER="opc"
	METADATA_URL_PATH="opc/v1/instance/"
	SSH_KEY_URL="metadata/ssh_authorized_keys"
	;;
esac


ec2_hostname()
{
	# hostname may already be set via /etc/rc.d/network
	if [ -n "$hostname" ] || [ -f /etc/myname ]; then
		return
	fi

	(
	umask 022
	HOSTNAME=$(ftp -o - -q 2 "${METADATA_URL}${HOSTNAME_URL}")
	if [ -n "$HOSTNAME" ]; then
		echo "Setting ${CLOUD_TYPE} hostname: ${HOSTNAME}"
		echo "$HOSTNAME" > /etc/myname
		hostname "$HOSTNAME"
		break
	fi
	)
}

ec2_init()
{
	ec2_metadata
	ec2_hostname
	ec2_user
	ec2_random_seed
}


ec2_metadata()
{
	local imds="${IMDS_IP}"

	# It may be 5-10 seconds for the metadata service
	# to become reachable.  Try IPv4 first (AWS does not
	# enable the IPv6 metadata endpoint by default), then
	# IPv6 and use whichever works.
	try=0
	while [ $((try++)) -lt 20 ]
	do
		ftp -o /dev/null -q 2 http://${IMDS_IP}/${METADATA_URL_PATH}/${HOSTNAME_URL} >/dev/null 2>&1
		if [ $? -eq 0 ]; then
			break
		fi

		ftp -o /dev/null -q 2 http://[${IMDS_IPv6}]/${METADATA_URL_PATH}/${HOSTNAME_URL} >/dev/null 2>&1
		if [ $? -eq 0 ]; then
			imds="[${IMDS_IPv6}]"
			break
		fi

		echo "Metadata service not available yet (try $try / 20)..."
		sleep 1
	done

	METADATA_URL="http://${imds}/${METADATA_URL_PATH}"

	SSH_KEY_FILE="/home/${EC2_USER}/.ssh/authorized_keys"

	OS_METADATA_URL="http://${imds}/openstack/latest/meta_data.json"
}

ec2_newuser()
{
	echo "Creating ${CLOUD_TYPE} user account ${EC2_USER}"
	useradd -g users -G wheel,operator -m "${EC2_USER}"
}

ec2_random_seed()
{
	# May contain a "random_seed".
	OS_METADATA="$(ftp -o - -q 2 ${OS_METADATA_URL} 2>/dev/null)"
	if echo "$OS_METADATA" | grep -q random_seed; then
		echo "$OS_METADATA" | extract_random_seed |
		    base64 -di >> /dev/urandom
	fi
}

ec2_user()
{
	# create cloud user
	id "${EC2_USER}" >/dev/null 2>&1 || ec2_newuser

	# fetch the public key from the metadata service
	EC2_SSH_KEY=$(ftp -o - -q 2 "${METADATA_URL}${SSH_KEY_URL}")

	if [ -n "$EC2_SSH_KEY" ]; then
		# A key pair is associated with this instance, add it
		# to EC2_USER's 'authorized_keys' file
		mkdir -p $(dirname "$SSH_KEY_FILE")
		chown "${EC2_USER}:users" $(dirname "$SSH_KEY_FILE")
		touch "$SSH_KEY_FILE"
		chown "${EC2_USER}:users" "$SSH_KEY_FILE"
		cd $(dirname "$SSH_KEY_FILE")

		grep -q "$EC2_SSH_KEY" "$SSH_KEY_FILE"
		if [ $? -ne 0 ]; then
			echo "Setting ${CLOUD_TYPE} SSH public key for user ${EC2_USER}: ${EC2_SSH_KEY##* }"
			echo "$EC2_SSH_KEY" >> "$SSH_KEY_FILE"
		fi
	fi
}

extract_random_seed()
{
	sed -n -e '/random_seed/s/.*"random_seed": *"\([A-Za-z0-9+/=]*\)".*/\1/p'
}

load_rc_config $name
run_rc_command "$1"
@


1.7
log
@On IPv6-only instances, IMDS is available from [fd00:ec2::254]
@
text
@d3 1
a3 1
# $NetBSD: ec2_init,v 1.6 2023/09/27 00:27:07 riastradh Exp $
d16 2
d19 1
a19 6
if ! route get default >/dev/null 2>&1; then
	IMDS_IP="[fd00:ec2::254]"
fi

METADATA_URL="http://${IMDS_IP}/latest/meta-data/"
CLOUD_TYPE=EC2	# default
d21 1
d28 1
d32 1
a32 1
	METADATA_URL="http://${IMDS_IP}/latest/meta-data/"
d37 1
a37 1
	METADATA_URL="http://${IMDS_IP}/opc/v1/instance/"
a41 1
HOSTNAME_URL="hostname"
d43 6
a48 1
SSH_KEY_FILE="/home/${EC2_USER}/.ssh/authorized_keys"
d50 11
a60 1
OS_METADATA_URL="http://${IMDS_IP}/openstack/latest/meta_data.json"
d62 1
a62 1
ec2_newuser()
d64 4
a67 2
	echo "Creating ${CLOUD_TYPE} user account ${EC2_USER}"
	useradd -g users -G wheel,operator -m "${EC2_USER}"
a69 4
extract_random_seed()
{
	sed -n -e '/random_seed/s/.*"random_seed": *"\([A-Za-z0-9+/=]*\)".*/\1/p'
}
d71 1
a71 1
ec2_init()
d73 1
a73 2
	(
	umask 022
d75 4
a78 2
	# set hostname; it may be 5-10 seconds for the metadata service
	# to become reachable.
d82 2
a83 5
		HOSTNAME=$(ftp -o - -q 2 "${METADATA_URL}${HOSTNAME_URL}")
		if [ -n "$HOSTNAME" ]; then
			echo "Setting ${CLOUD_TYPE} hostname: ${HOSTNAME}"
			echo "$HOSTNAME" > /etc/myname
			hostname "$HOSTNAME"
d86 8
a93 1
		echo "${CLOUD_TYPE} hostname not available yet (try $try)"
d97 25
d143 1
d145 3
a147 7
	# May contain a "random_seed".
	OS_METADATA="$(ftp -o - -q 2 ${OS_METADATA_URL} 2>/dev/null)"
	if echo "$OS_METADATA" | grep -q random_seed; then
		echo "$OS_METADATA" | extract_random_seed |
		    base64 -di >> /dev/urandom
	fi
	)
@


1.6
log
@ec2_init: Suppress error message for nonexistent sysctl.

We're querying to see whether the sysctl node is available and if so
what its text is, not interested in the error message.

XXX pullup-10
@
text
@d3 1
a3 1
# $NetBSD: ec2_init,v 1.5 2022/10/15 18:32:30 jmcneill Exp $
d16 6
d33 1
a33 1
	METADATA_URL="http://169.254.169.254/latest/meta-data/"
d38 1
a38 1
	METADATA_URL="http://169.254.169.254/opc/v1/instance/"
d47 1
a47 1
OS_METADATA_URL="http://169.254.169.254/openstack/latest/meta_data.json"
d104 1
a104 1
	OS_METADATA="$(ftp -o - -q 2 ${OS_METADATA_URL})"
@


1.5
log
@ec2_init: Add support for Oracle Cloud
@
text
@d3 1
a3 1
# $NetBSD: ec2_init,v 1.4 2021/07/20 19:31:23 rhialto Exp $
d18 1
a18 1
case "$(/sbin/sysctl -n machdep.dmi.chassis-asset-tag)" in
@


1.5.2.1
log
@Pull up following revision(s) (requested by riastradh in ticket #382):

	distrib/utils/embedded/files/ec2_init: revision 1.6

ec2_init: Suppress error message for nonexistent sysctl.

We're querying to see whether the sysctl node is available and if so
what its text is, not interested in the error message.
@
text
@d3 1
a3 1
# $NetBSD: ec2_init,v 1.5 2022/10/15 18:32:30 jmcneill Exp $
d18 1
a18 1
case "$(/sbin/sysctl -n machdep.dmi.chassis-asset-tag 2>/dev/null)" in
@


1.4
log
@Extract just the random bits to feed to /dev/urandom.

This makes no difference in the randomness of the pool, but it improves
on the estimation (if any) of how many random bits were obtained.
Also make the ftp -q time out a bit longer since I got some time outs.
@
text
@d3 1
a3 1
# $NetBSD: ec2_init,v 1.3 2021/07/15 19:03:17 rhialto Exp $
d16 21
a36 3
EC2_USER="ec2-user"
METADATA_URL="http://169.254.169.254/latest/meta-data/"
SSH_KEY_URL="public-keys/0/openssh-key"
d45 1
a45 1
	echo "Creating EC2 user account ${EC2_USER}"
d60 1
a60 1
	# to  become reachable.
d66 1
a66 1
			echo "Setting EC2 hostname: ${HOSTNAME}"
d71 1
a71 1
		echo "EC2 hostname not available yet (try $try)"
d75 1
a75 1
	# create EC2 user
d78 1
a78 1
	# fetch the public key from Amazon Web Services
d92 1
a92 1
			echo "Setting EC2 SSH public key for user ${EC2_USER}: ${EC2_SSH_KEY##* }"
@


1.3
log
@Add some OpenStack support.

I found that in the cloud I tried, by the time this script runs, there
is no default route in effect yet. That takes some 5 to 10 seconds
longer. So I added a retry loop, and to make that easier, changed the
order of queries.  To make sure it doesn't wait ~forever for a
non-existent service I added the -q 1 option to ftp invocations.

I also added OpenStack-specific metadata which contains a different
random_seed of 512 bytes every time it is requested.  See
https://github.com/openstack/nova/blob/master/nova/api/metadata/base.py#L355
It may not be trusted data but only in the strictest sense of the word.
The data can only be observed by people with access to the cloud's
overlay network for the particular VM.
@
text
@d3 1
a3 1
# $NetBSD: ec2_init,v 1.2 2021/07/01 18:05:45 jmcneill Exp $
d31 5
d46 1
a46 1
		HOSTNAME=$(ftp -o - -q 1 "${METADATA_URL}${HOSTNAME_URL}")
d61 1
a61 1
	EC2_SSH_KEY=$(ftp -o - -q 1 "${METADATA_URL}${SSH_KEY_URL}")
d79 2
a80 2
	# May contain a "random_seed". Everything else doesn't matter.
	OS_METADATA="$(ftp -o - -q 1 ${OS_METADATA_URL})"
d82 2
a83 1
		echo "$OS_METADATA" >> /dev/urandom
@


1.2
log
@AWS marketplace does not allow root ssh logins. Create an ec2-user account
and install the ssh key in that user's home directory instead.
@
text
@d3 1
a3 1
# $NetBSD: ec2_init,v 1.1 2018/11/30 20:53:02 jmcneill Exp $
d23 2
d36 16
d55 2
a56 2
	# fetch the key pair from Amazon Web Services
	EC2_SSH_KEY=$(ftp -o - "${METADATA_URL}${SSH_KEY_URL}")
d69 1
a69 1
			echo "Setting EC2 SSH key pair: ${EC2_SSH_KEY##* }"
d74 5
a78 5
	# set hostname
	HOSTNAME=$(ftp -o - "${METADATA_URL}${HOSTNAME_URL}")
	echo "Setting EC2 hostname: ${HOSTNAME}"
	echo "$HOSTNAME" > /etc/myname
	hostname "$HOSTNAME"
@


1.1
log
@Add support for configuring Amazon.com EC2 SSH keys and hostnames. While
here, only set wscons=YES if a wsdisplay0 device is present.
@
text
@d3 1
a3 1
# $NetBSD$
d16 1
d21 7
a27 1
SSH_KEY_FILE="/root/.ssh/authorized_keys"
d33 4
d42 1
a42 1
		# to root 'authorized_keys' file
d44 1
d46 1
@


1.1.4.1
log
@file ec2_init was added on branch phil-wifi on 2019-06-10 21:42:37 +0000
@
text
@d1 52
@


1.1.4.2
log
@Sync with HEAD
@
text
@a0 52
#!/bin/sh
#
# $NetBSD: ec2_init,v 1.1 2018/11/30 20:53:02 jmcneill Exp $
#
# PROVIDE: ec2_init
# REQUIRE: NETWORKING
# BEFORE:  LOGIN

$_rc_subr_loaded . /etc/rc.subr

name="ec2_init"
rcvar=${name}
start_cmd="ec2_init"
stop_cmd=":"

METADATA_URL="http://169.254.169.254/latest/meta-data/"
SSH_KEY_URL="public-keys/0/openssh-key"
HOSTNAME_URL="hostname"

SSH_KEY_FILE="/root/.ssh/authorized_keys"

ec2_init()
{
	(
	umask 022
	# fetch the key pair from Amazon Web Services
	EC2_SSH_KEY=$(ftp -o - "${METADATA_URL}${SSH_KEY_URL}")

	if [ -n "$EC2_SSH_KEY" ]; then
		# A key pair is associated with this instance, add it
		# to root 'authorized_keys' file
		mkdir -p $(dirname "$SSH_KEY_FILE")
		touch "$SSH_KEY_FILE"
		cd $(dirname "$SSH_KEY_FILE")

		grep -q "$EC2_SSH_KEY" "$SSH_KEY_FILE"
		if [ $? -ne 0 ]; then
			echo "Setting EC2 SSH key pair: ${EC2_SSH_KEY##* }"
			echo "$EC2_SSH_KEY" >> "$SSH_KEY_FILE"
		fi
	fi

	# set hostname
	HOSTNAME=$(ftp -o - "${METADATA_URL}${HOSTNAME_URL}")
	echo "Setting EC2 hostname: ${HOSTNAME}"
	echo "$HOSTNAME" > /etc/myname
	hostname "$HOSTNAME"
	)
}

load_rc_config $name
run_rc_command "$1"
@


1.1.2.1
log
@file ec2_init was added on branch pgoyette-compat on 2018-12-26 14:01:13 +0000
@
text
@d1 52
@


1.1.2.2
log
@Sync with HEAD, resolve a few conflicts
@
text
@a0 52
#!/bin/sh
#
# $NetBSD$
#
# PROVIDE: ec2_init
# REQUIRE: NETWORKING
# BEFORE:  LOGIN

$_rc_subr_loaded . /etc/rc.subr

name="ec2_init"
rcvar=${name}
start_cmd="ec2_init"
stop_cmd=":"

METADATA_URL="http://169.254.169.254/latest/meta-data/"
SSH_KEY_URL="public-keys/0/openssh-key"
HOSTNAME_URL="hostname"

SSH_KEY_FILE="/root/.ssh/authorized_keys"

ec2_init()
{
	(
	umask 022
	# fetch the key pair from Amazon Web Services
	EC2_SSH_KEY=$(ftp -o - "${METADATA_URL}${SSH_KEY_URL}")

	if [ -n "$EC2_SSH_KEY" ]; then
		# A key pair is associated with this instance, add it
		# to root 'authorized_keys' file
		mkdir -p $(dirname "$SSH_KEY_FILE")
		touch "$SSH_KEY_FILE"
		cd $(dirname "$SSH_KEY_FILE")

		grep -q "$EC2_SSH_KEY" "$SSH_KEY_FILE"
		if [ $? -ne 0 ]; then
			echo "Setting EC2 SSH key pair: ${EC2_SSH_KEY##* }"
			echo "$EC2_SSH_KEY" >> "$SSH_KEY_FILE"
		fi
	fi

	# set hostname
	HOSTNAME=$(ftp -o - "${METADATA_URL}${HOSTNAME_URL}")
	echo "Setting EC2 hostname: ${HOSTNAME}"
	echo "$HOSTNAME" > /etc/myname
	hostname "$HOSTNAME"
	)
}

load_rc_config $name
run_rc_command "$1"
@


