Open hc-github-team-packer opened 3 years ago
Hi @create-atl-delete thanks for reaching out. I will take a look as soon as I can to see if I can reproduce. In the meantime, the SSH connection over session manager uses a local tunnel to proxy the SSH connection over. More specifically, Packer will try to SSH to the localhost:dynamic-port and not directly to the remote instance like you are doing via ssh. Is it possible that this is being blocked.
While the ec2 instance is running what error do you get when you try running
ssh -i <cert_packer_made.pem> Administrator@127.0.0.1:49851
?
Note that the port 49851 may not be valid at the next run as Packer will find an available port and use that for the connection. You can see the port in the output of the Packer build.
Hi @nywilken
When I attempt the SSH connection that way you have suggested, I get the following.
ssh: Could not resolve hostname 127.0.0.1:8449: No such host is known.
However, if I run a Get-NetTCPConnection
, I can see that 127.0.0.1:8449 is Listening.
I neglected to mention in the original post that I have also disabled the Windows firewall on this instance as part of the user_data_file for troubleshooting purposes, so I'm not sure what could be blocking. Does Packer have an example user_data_file with an SSH configuration that is known to work with SSH over SSM?
@nywilken,
Correction to my previous reply, ssh -i <cert_packer_made.pem> Administrator@127.0.0.1
does work. The problem I was having was due to the syntax. It's not Administrator@127.0.0.1:<port>
. It is Administrator@127.0.0.1 -p <port>
.
Being able to properly test SSH to localhost revealed the source of the problem... The public key Packer (and I, during my testing) were attempting to use wasn't valid for use with SSH.
This is because the private key from the pair Packer generates during launch does not exist in %PROGRAMDATA%/.ssh/administrators_authorized_keys
by default. This isn't an issue with Linux builds, but it is with Windows. This has less to do with Packer and more to do with how OpenSSH works on Windows. It seems obvious now, but I overlooked it because there is currently no documentation on using SSH over SSM for Windows builds. Everything "just works" with Linux and I was expecting the same with Windows.
The solution is to save the private key (available in the instance metadata) to administrators_authorized_keys. Below is the user_data_file I am now using, which works with Amazon Server 2019 AMIs.
<powershell>
# Install sshd
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
# Save the private key from intance metadata
New-Item -Path C:\Windows\System32\OpenSSH\administrators_authorized_keys -ItemType File
Set-Content -Path C:\Windows\System32\OpenSSH\administrators_authorized_keys -Value ((New-Object System.Net.WebClient).DownloadString('http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key'))
# Set appropriate permissions on administrators_authorized_keys by copying them from an existing key
Get-ACL C:\ProgramData\ssh\ssh_host_dsa_key | Set-ACL C:\ProgramData\ssh\administrators_authorized_keys
# Set sshd to automatic and start
Set-Service -Name sshd -StartupType "Automatic"
Start-Service sshd
# Set ssh-agent to automatic and start
# Must set to automatic first as the default state is disabled
Set-Service -Name ssh-agent -StartupType "Automatic"
Start-Service ssh-agent
# Set default shell to PS
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force
</powershell>
If you ever get around to documenting SSH over SSM on Windows, I recommend including the above.
@nywilken @create-atl-delete I've used the above user_data_file and successfully authenticated via SSH over SSM on Windows. However, my PowerShell scripts are not executing on the packer builder instance. It looks like an issue with the shell with the SSH communicator in the PowerShell provisioner. What my PowerShell script does is download a couple of packages (like MSEdge browser and Symon) and install them on the instance. I'm getting the following error while doing the packer build:
base-ami-windows-builder.amazon-ebs.windows-base-ami: Adding tag: "Name": "Packer Builder"
base-ami-windows-builder.amazon-ebs.windows-base-ami: Instance ID: i-0f03b00afd90f9f16
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: Waiting for instance (i-0f03b00afd90f9f16) to become ready...
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: Using SSH communicator to connect: localhost
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: Waiting for SSH to become available...
base-ami-windows-builder.amazon-ebs.windows-base-ami: Starting portForwarding session "ns.com-0c4ad564a90e86797".
base-ami-windows-builder.amazon-ebs.windows-base-ami: Starting session with SessionId: ns.com-0c4ad564a90e86797
base-ami-windows-builder.amazon-ebs.windows-base-ami: Port 8807 opened for sessionId ns.com-0c4ad564a90e86797.
base-ami-windows-builder.amazon-ebs.windows-base-ami: Waiting for connections...
base-ami-windows-builder.amazon-ebs.windows-base-ami: Connection accepted for session [ns.com-0c4ad564a90e86797]
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: Connected to SSH!
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: Provisioning with Powershell...
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: Provisioning with powershell script: /var/folders/2j/s33gtchs13n2jkn_6qc8w0fm0000gn/T/powershell-provisioner37195405
base-ami-windows-builder.amazon-ebs.windows-base-ami: Hello from PowerShell
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: Provisioning with Powershell...
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: Provisioning with powershell script: ./basic-tools-installation.ps1
base-ami-windows-builder.amazon-ebs.windows-base-ami: Folder doesn't exists
base-ami-windows-builder.amazon-ebs.windows-base-ami:
base-ami-windows-builder.amazon-ebs.windows-base-ami:
base-ami-windows-builder.amazon-ebs.windows-base-ami: Directory: C:\
base-ami-windows-builder.amazon-ebs.windows-base-ami:
base-ami-windows-builder.amazon-ebs.windows-base-ami:
base-ami-windows-builder.amazon-ebs.windows-base-ami: Mode LastWriteTime Length Name
base-ami-windows-builder.amazon-ebs.windows-base-ami: ---- ------------- ------ ----
base-ami-windows-builder.amazon-ebs.windows-base-ami: d----- 6/16/2022 2:35 PM setupfiles
base-ami-windows-builder.amazon-ebs.windows-base-ami:
base-ami-windows-builder.amazon-ebs.windows-base-ami:
base-ami-windows-builder.amazon-ebs.windows-base-ami: Directory: C:\setupfiles
base-ami-windows-builder.amazon-ebs.windows-base-ami:
base-ami-windows-builder.amazon-ebs.windows-base-ami:
base-ami-windows-builder.amazon-ebs.windows-base-ami: Mode LastWriteTime Length Name
base-ami-windows-builder.amazon-ebs.windows-base-ami: ---- ------------- ------ ----
base-ami-windows-builder.amazon-ebs.windows-base-ami: d----- 6/16/2022 2:35 PM logs
base-ami-windows-builder.amazon-ebs.windows-base-ami: Created folders
base-ami-windows-builder.amazon-ebs.windows-base-ami: The FolderName is C:\setupfiles
base-ami-windows-builder.amazon-ebs.windows-base-ami: The LogFolderName is C:\setupfiles\logs
base-ami-windows-builder.amazon-ebs.windows-base-ami: Installing Microsoft Edge browser
base-ami-windows-builder.amazon-ebs.windows-base-ami: The Download path is C:\Users\Administrator\AppData\Local\Temp\edgeinstall\MicrosoftEdgeEnterpriseX64.msi
base-ami-windows-builder.amazon-ebs.windows-base-ami: Verifying Microsoft Edge browser installation...
base-ami-windows-builder.amazon-ebs.windows-base-ami:
base-ami-windows-builder.amazon-ebs.windows-base-ami:
base-ami-windows-builder.amazon-ebs.windows-base-ami:
base-ami-windows-builder.amazon-ebs.windows-base-ami: DisplayName DisplayVersion Publisher InstallDate
base-ami-windows-builder.amazon-ebs.windows-base-ami: ----------- -------------- --------- -----------
base-ami-windows-builder.amazon-ebs.windows-base-ami: Microsoft Edge Update 1.3.145.49
base-ami-windows-builder.amazon-ebs.windows-base-ami:
base-ami-windows-builder.amazon-ebs.windows-base-ami:
base-ami-windows-builder.amazon-ebs.windows-base-ami: Retrieving Sysmon...
base-ami-windows-builder.amazon-ebs.windows-base-ami: Sysmon Retrived
base-ami-windows-builder.amazon-ebs.windows-base-ami: Changing working directory to C:\setupfiles
base-ami-windows-builder.amazon-ebs.windows-base-ami: Unzip Sysmon...
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: Write-Progress : Win32 internal error "Access is denied" 0x5 occurred while reading the console output buffer. Contact
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: Microsoft Customer Support Services.
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: At
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.psm1:1132
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: char:9
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: + Write-Progress -Activity $cmdletName -Status $status -Percent ...
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: + CategoryInfo : ReadError: (:) [Write-Progress], HostException
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: + FullyQualifiedErrorId : ReadConsoleOutput,Microsoft.PowerShell.Commands.WriteProgressCommand
==> base-ami-windows-builder.amazon-ebs.windows-base-ami:
base-ami-windows-builder.amazon-ebs.windows-base-ami: Unzip Complete.
base-ami-windows-builder.amazon-ebs.windows-base-ami: Retrieving Configuration File...
base-ami-windows-builder.amazon-ebs.windows-base-ami: Configuration File Retrieved.
base-ami-windows-builder.amazon-ebs.windows-base-ami: Installing Sysmon...
==> base-ami-windows-builder.amazon-ebs.windows-base-ami:
base-ami-windows-builder.amazon-ebs.windows-base-ami:
base-ami-windows-builder.amazon-ebs.windows-base-ami: System Monitor v13.34 - System activity monitor
base-ami-windows-builder.amazon-ebs.windows-base-ami: By Mark Russinovich and Thomas Garnier
base-ami-windows-builder.amazon-ebs.windows-base-ami: Copyright (C) 2014-2022 Microsoft Corporation
base-ami-windows-builder.amazon-ebs.windows-base-ami: Using libxml2. libxml2 is Copyright (C) 1998-2012 Daniel Veillard. All Rights Reserved.
base-ami-windows-builder.amazon-ebs.windows-base-ami: Sysinternals - www.sysinternals.com
base-ami-windows-builder.amazon-ebs.windows-base-ami:
base-ami-windows-builder.amazon-ebs.windows-base-ami: Loading configuration file with schema version 4.50
base-ami-windows-builder.amazon-ebs.windows-base-ami: Sysmon schema version: 4.81
base-ami-windows-builder.amazon-ebs.windows-base-ami: Configuration file validated.
base-ami-windows-builder.amazon-ebs.windows-base-ami: Sysmon64 installed.
base-ami-windows-builder.amazon-ebs.windows-base-ami: SysmonDrv installed.
base-ami-windows-builder.amazon-ebs.windows-base-ami: Starting SysmonDrv.
base-ami-windows-builder.amazon-ebs.windows-base-ami: SysmonDrv started.
base-ami-windows-builder.amazon-ebs.windows-base-ami: Starting Sysmon64..
base-ami-windows-builder.amazon-ebs.windows-base-ami: Sysmon64 started.
base-ami-windows-builder.amazon-ebs.windows-base-ami: Sysmon Installed!
base-ami-windows-builder.amazon-ebs.windows-base-ami: Windows defender is enabled
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: Exception calling "EndProcessing" with "0" argument(s): "Win32 internal error "Access is denied" 0x5 occurred while
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: reading the console output buffer. Contact Microsoft Customer Support Services."
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: At line:146 char:17
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: + $__cmdletization_objectModelWrapper.EndProcessing()
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: + CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: + FullyQualifiedErrorId : HostException
==> base-ami-windows-builder.amazon-ebs.windows-base-ami:
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: Provisioning step had errors: Running the cleanup provisioner, if present...
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: Terminating the source AWS instance...
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: Bad exit status: -1
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: Cleaning up any extra volumes...
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: No volumes to clean up, skipping
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: Deleting temporary security group...
==> base-ami-windows-builder.amazon-ebs.windows-base-ami: Deleting temporary keypair...
Build 'base-ami-windows-builder.amazon-ebs.windows-base-ami' errored after 11 minutes 9 seconds: Script exited with non-zero exit status: 1.Allowed exit codes are: [0]
==> Wait completed after 11 minutes 9 seconds
I've tried the execute_command
specified in the Packer documentation, but getting the same error.
execute_command = "powershell -executionpolicy bypass \"& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }\""
My PowerShell script:
$FolderName = "C:\setupfiles"
$LogFolderName = "$FolderName\logs"
if(Get-Item -Path $FolderName -ErrorAction Ignore)
{
Write-Host "Folder Exists"
#Create logs folder
if(Get-Item -Path $LogFolderName -ErrorAction Ignore)
{
Write-Host "Logs folder already exists"
}
else
{
# PowerShell create logs directory if not exists
Write-Host "Creating log folder"
New-Item $LogFolderName -ItemType Directory
}
}
else
{
Write-Host "Folder doesn't exists"
# PowerShell create directories if not exists
New-Item $FolderName -ItemType Directory
New-Item $LogFolderName -ItemType Directory
Write-Host "Created folders"
}
Write-Host "The FolderName is $FolderName"
Write-Host "The LogFolderName is $LogFolderName"
# Installing Microsoft Edge browser
Write-Host "Installing Microsoft Edge browser"
md -Path $env:temp\edgeinstall -erroraction SilentlyContinue | Out-Null
$Download = join-path $env:temp\edgeinstall MicrosoftEdgeEnterpriseX64.msi
Write-Host "The Download path is $Download"
Invoke-WebRequest 'https://msedge.sf.dl.delivery.mp.microsoft.com/filestreamingservice/files/a2662b5b-97d0-4312-8946-598355851b3b/MicrosoftEdgeEnterpriseX64.msi' -OutFile $Download
Start-Process "$Download" -ArgumentList "/quiet"
Start-Sleep -Seconds 30
# Verifying Microsoft Edge installation
Write-Host "Verifying Microsoft Edge browser installation..."
$INSTALLED = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate
$INSTALLED += Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate
$INSTALLED | ?{ $_.DisplayName -match 'edge' } | sort-object -Property DisplayName -Unique | Format-Table -AutoSize
# SysMon Installation
Write-Host "Retrieving Sysmon..."
Invoke-WebRequest -Uri https://download.sysinternals.com/files/Sysmon.zip -Outfile $FolderName\Sysmon.zip
Write-Host "Sysmon Retrived"
Write-Host "Changing working directory to $FolderName"
Set-Location $FolderName
Write-Host "Unzip Sysmon..."
Expand-Archive Sysmon.zip
Set-Location $FolderName\Sysmon
Write-Host "Unzip Complete."
Write-Host "Retrieving Configuration File..."
Invoke-WebRequest -Uri https://raw.githubusercontent.com/SwiftOnSecurity/sysmon-config/master/sysmonconfig-export.xml -Outfile sysmonconfig-export.xml
Write-Host "Configuration File Retrieved."
Write-Host "Installing Sysmon..."
.\sysmon64.exe -accepteula -i sysmonconfig-export.xml
Write-Host "Sysmon Installed!"
# Check the status of Windows Defender
$Windows_Defender_status = Get-MpComputerStatus
if ($Windows_Defender_status.AntivirusEnabled -eq "true")
{
Write-Output "Windows defender is enabled"
Update-MpSignature -UpdateSource MicrosoftUpdateServer
}
else
{
Write-Output "Installing Windows defender...."
Add-WindowsFeature Windows-Defender
}
Used the following Packer template:
source "amazon-ebs" "windows-base-ami" {
source_ami = "ami-07d4836e0aad1ece7"
instance_type = "${var.aws_instance_type}"
ami_name = "${var.ami_name}-${local.timestamp}-${var.regionAbbreviation}-${var.aws_env}"
shutdown_behavior = "terminate"
subnet_id = "${var.aws_subnet_id}"
vpc_id = "${var.aws_vpc_id}"
region = "${var.aws_region}"
iam_instance_profile = var.iam_instance_profile
ssh_username = "Administrator"
ssh_timeout = "22h"
ssh_interface = "session_manager"
communicator = "ssh"
ssh_port = 22
user_data_file = "./openssh-user-data.ps1"
launch_block_device_mappings {
device_name = "/dev/sda1"
volume_size = 40
volume_type = "gp2"
delete_on_termination = true
}
}
build {
name = "base-ami-windows-builder"
sources = ["source.amazon-ebs.windows-base-ami"]
provisioner "powershell" {
execute_command = "powershell -executionpolicy bypass \"& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }\""
script = "./basic-tools-installation.ps1"
}
}
user_data_file (openssh-user-data.ps1 in the template above):
<powershell>
# Install sshd
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
# Save the private key from intance metadata
# New-Item -Path C:\Windows\System32\OpenSSH\administrators_authorized_keys -ItemType File
# Set-Content -Path C:\Windows\System32\OpenSSH\administrators_authorized_keys -Value ((New-Object System.Net.WebClient).DownloadString('http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key'))
# Save the private key from intance metadata
New-Item -Path C:\ProgramData\ssh\administrators_authorized_keys -ItemType File
Set-Content -Path C:\ProgramData\ssh\administrators_authorized_keys -Value ((New-Object System.Net.WebClient).DownloadString('http://169.254.169.254/latest/meta-data/public-keys/0/openssh-key'))
# Set sshd to automatic and start
Set-Service -Name sshd -StartupType "Automatic"
Start-Service sshd
# Set appropriate permissions on administrators_authorized_keys by copying them from an existing key
Get-ACL C:\ProgramData\ssh\ssh_host_dsa_key | Set-ACL C:\ProgramData\ssh\administrators_authorized_keys
# Set ssh-agent to automatic and start
# Must set to automatic first as the default state is disabled
Set-Service -Name ssh-agent -StartupType "Automatic"
Start-Service ssh-agent
######## TRIED THIS, BUT DIDN'T WORK ########
# Set default shell to PS \\ TRIED THIS, BUT DIDN'T WORK
# New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force
######## TRIED THIS, BUT DIDN'T WORK ########
</powershell>
The same PowerShell script worked with the WinRM communicator. Is there any issue in executing PowerShell script through the SSH communicator?
any updates about this issue? I'm having the same error.
This issue was originally opened by @create-atl-delete in https://github.com/hashicorp/packer/issues/11199 and has been migrated to this repository. The original issue description is below.
Overview of the Issue
I'm attempting to use Packer to build Server 2019 AMIs using the SSH communicator running over Session Manager (SSM). Packer consistently errors out like so:
original error: ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain
If I keep the Packer instance up after this error, I can connect to it via SSH over SSM from Powershell using
ssh -i <cert_packer_made.pem> Administrator@<instanceid>
and providing the password, which I can decrypt using that same certificate in the EC2 console.This proves that:
From my perspective, Packer has everything it needs to properly authenticate and is failing to so. On the Packer instance, I see the following in the event logs:
Reproduction Steps
Try the below build or any build using an Amazon Sever 2019 AMI and SSH over SSM. In my testing, the same issue occurs regardless of VPC/subnet and the particular AMI version.
Packer version
1.74
Simplified Packer Buildfile
Operating system and Environment details
I'm running Packer from a Windows 10 host with:
Log Fragments and crash.log files
2021/08/11 15:05:24 ui: ==> amazon-ebs.stage1: Waiting for SSH to become available... 2021/08/11 15:05:25 ui: amazon-ebs.stage1: Starting session with SessionId: omitted@domain.com-0c14bf492290fc4e6 2021/08/11 15:05:25 ui: amazon-ebs.stage1: Port 8746 opened for sessionId omitted@domain.com-0c14bf492290fc4e6. 2021/08/11 15:05:25 ui: amazon-ebs.stage1: Waiting for connections... 2021/08/11 15:05:25 ui: amazon-ebs.stage1: Connection accepted for session [omitted@domain.com-0c14bf492290fc4e6] 2021/08/11 15:05:25 packer-plugin-amazon_v1.0.0_x5.0_windows_amd64.exe plugin: 2021/08/11 15:05:25 [INFO] Attempting SSH connection to localhost:8746... 2021/08/11 15:05:25 packer-plugin-amazon_v1.0.0_x5.0_windows_amd64.exe plugin: 2021/08/11 15:05:25 [DEBUG] reconnecting to TCP connection for SSH 2021/08/11 15:05:25 packer-plugin-amazon_v1.0.0_x5.0_windows_amd64.exe plugin: 2021/08/11 15:05:25 [DEBUG] handshaking with SSH 2021/08/11 15:05:25 packer-plugin-amazon_v1.0.0_x5.0_windows_amd64.exe plugin: 2021/08/11 15:05:25 [DEBUG] SSH handshake err: ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain 2021/08/11 15:05:25 packer-plugin-amazon_v1.0.0_x5.0_windows_amd64.exe plugin: 2021/08/11 15:05:25 [DEBUG] Detected authentication error. Increasing handshake attempts. ... above few lines repeat several times ... 2021/08/11 15:06:32 ui error: ==> amazon-ebs.stage1: Error waiting for SSH: Packer experienced an authentication error when trying to connect via SSH. This can happen if your username/password are wrong. You may want to double-check your credentials as part of your debugging process. original error: ssh: handshake failed: ssh: unable to authenticate, attempted methods [none publickey], no supported methods remain