Home | History | Annotate | Line # | Download | only in files
      1 #!/bin/sh
      2 #
      3 # $NetBSD: ec2_init,v 1.8 2026/05/16 20:59:59 jschauma Exp $
      4 #
      5 # PROVIDE: ec2_init
      6 # REQUIRE: NETWORKING
      7 # BEFORE:  LOGIN
      8 
      9 $_rc_subr_loaded . /etc/rc.subr
     10 
     11 name="ec2_init"
     12 rcvar=${name}
     13 start_cmd="ec2_init"
     14 stop_cmd=":"
     15 
     16 HOSTNAME_URL="hostname"
     17 
     18 IMDS_IP="169.254.169.254"
     19 IMDS_IPv6="fd00:ec2::254"
     20 
     21 CLOUD_TYPE=EC2
     22 case "$(/sbin/sysctl -n machdep.dmi.chassis-asset-tag 2>/dev/null)" in
     23 OracleCloud*)
     24 	CLOUD_TYPE=OCI
     25 	;;
     26 esac
     27 
     28 EC2_USER="ec2-user"
     29 case ${CLOUD_TYPE} in
     30 EC2)
     31 	EC2_USER="ec2-user"
     32 	METADATA_URL_PATH="latest/meta-data/"
     33 	SSH_KEY_URL="public-keys/0/openssh-key"
     34 	;;
     35 OCI)
     36 	EC2_USER="opc"
     37 	METADATA_URL_PATH="opc/v1/instance/"
     38 	SSH_KEY_URL="metadata/ssh_authorized_keys"
     39 	;;
     40 esac
     41 
     42 
     43 ec2_hostname()
     44 {
     45 	# hostname may already be set via /etc/rc.d/network
     46 	if [ -n "$hostname" ] || [ -f /etc/myname ]; then
     47 		return
     48 	fi
     49 
     50 	(
     51 	umask 022
     52 	HOSTNAME=$(ftp -o - -q 2 "${METADATA_URL}${HOSTNAME_URL}")
     53 	if [ -n "$HOSTNAME" ]; then
     54 		echo "Setting ${CLOUD_TYPE} hostname: ${HOSTNAME}"
     55 		echo "$HOSTNAME" > /etc/myname
     56 		hostname "$HOSTNAME"
     57 		break
     58 	fi
     59 	)
     60 }
     61 
     62 ec2_init()
     63 {
     64 	ec2_metadata
     65 	ec2_hostname
     66 	ec2_user
     67 	ec2_random_seed
     68 }
     69 
     70 
     71 ec2_metadata()
     72 {
     73 	local imds="${IMDS_IP}"
     74 
     75 	# It may be 5-10 seconds for the metadata service
     76 	# to become reachable.  Try IPv4 first (AWS does not
     77 	# enable the IPv6 metadata endpoint by default), then
     78 	# IPv6 and use whichever works.
     79 	try=0
     80 	while [ $((try++)) -lt 20 ]
     81 	do
     82 		ftp -o /dev/null -q 2 http://${IMDS_IP}/${METADATA_URL_PATH}/${HOSTNAME_URL} >/dev/null 2>&1
     83 		if [ $? -eq 0 ]; then
     84 			break
     85 		fi
     86 
     87 		ftp -o /dev/null -q 2 http://[${IMDS_IPv6}]/${METADATA_URL_PATH}/${HOSTNAME_URL} >/dev/null 2>&1
     88 		if [ $? -eq 0 ]; then
     89 			imds="[${IMDS_IPv6}]"
     90 			break
     91 		fi
     92 
     93 		echo "Metadata service not available yet (try $try / 20)..."
     94 		sleep 1
     95 	done
     96 
     97 	METADATA_URL="http://${imds}/${METADATA_URL_PATH}"
     98 
     99 	SSH_KEY_FILE="/home/${EC2_USER}/.ssh/authorized_keys"
    100 
    101 	OS_METADATA_URL="http://${imds}/openstack/latest/meta_data.json"
    102 }
    103 
    104 ec2_newuser()
    105 {
    106 	echo "Creating ${CLOUD_TYPE} user account ${EC2_USER}"
    107 	useradd -g users -G wheel,operator -m "${EC2_USER}"
    108 }
    109 
    110 ec2_random_seed()
    111 {
    112 	# May contain a "random_seed".
    113 	OS_METADATA="$(ftp -o - -q 2 ${OS_METADATA_URL} 2>/dev/null)"
    114 	if echo "$OS_METADATA" | grep -q random_seed; then
    115 		echo "$OS_METADATA" | extract_random_seed |
    116 		    base64 -di >> /dev/urandom
    117 	fi
    118 }
    119 
    120 ec2_user()
    121 {
    122 	# create cloud user
    123 	id "${EC2_USER}" >/dev/null 2>&1 || ec2_newuser
    124 
    125 	# fetch the public key from the metadata service
    126 	EC2_SSH_KEY=$(ftp -o - -q 2 "${METADATA_URL}${SSH_KEY_URL}")
    127 
    128 	if [ -n "$EC2_SSH_KEY" ]; then
    129 		# A key pair is associated with this instance, add it
    130 		# to EC2_USER's 'authorized_keys' file
    131 		mkdir -p $(dirname "$SSH_KEY_FILE")
    132 		chown "${EC2_USER}:users" $(dirname "$SSH_KEY_FILE")
    133 		touch "$SSH_KEY_FILE"
    134 		chown "${EC2_USER}:users" "$SSH_KEY_FILE"
    135 		cd $(dirname "$SSH_KEY_FILE")
    136 
    137 		grep -q "$EC2_SSH_KEY" "$SSH_KEY_FILE"
    138 		if [ $? -ne 0 ]; then
    139 			echo "Setting ${CLOUD_TYPE} SSH public key for user ${EC2_USER}: ${EC2_SSH_KEY##* }"
    140 			echo "$EC2_SSH_KEY" >> "$SSH_KEY_FILE"
    141 		fi
    142 	fi
    143 }
    144 
    145 extract_random_seed()
    146 {
    147 	sed -n -e '/random_seed/s/.*"random_seed": *"\([A-Za-z0-9+/=]*\)".*/\1/p'
    148 }
    149 
    150 load_rc_config $name
    151 run_rc_command "$1"
    152