大体ここのおかげ。
# インストール
Install-WindowsFeature -Name Web-Ftp-Server -IncludeAllSubFeature -IncludeManagementTools
# FTP サイトの名前
$ftpsite = "hogehoge"
# EC2インスタンスのパブリックIP
$publicip = "10.0.0.1"
# FTP サイトの作成
# https://codeday.me/jp/qa/20190412/611354.html
New-WebFtpSite -Name $ftpsite -Port 21 -Force
cmd /c \Windows\System32\inetsrv\appcmd set SITE $ftpsite "-virtualDirectoryDefaults.physicalPath:C:\inetpub\ftproot"
# 非SSL接続の許可
Set-ItemProperty "IIS:\Sites\$ftpsite" -Name ftpServer.security.ssl.controlChannelPolicy -Value 0
Set-ItemProperty "IIS:\Sites\$ftpsite" -Name ftpServer.security.ssl.dataChannelPolicy -Value 0
# BASIC 認証を有効化
Set-ItemProperty "IIS:\Sites\$ftpsite" -Name ftpServer.security.authentication.basicAuthentication.enabled -Value $true
# ユーザの分離を有効化
# https://docs.microsoft.com/en-us/iis/configuration/system.applicationhost/sites/site/ftpserver/userisolation/
Set-ItemProperty "IIS:\Sites\$ftpsite" -Name ftpserver.userisolation.mode -Value 3
# FTPユーザの権限を付与
Add-WebConfiguration "/system.ftpServer/security/authorization" -value @{accessType="Allow";roles="";permissions="Read,Write";users="*"} -PSPath IIS:\ -location $ftpsite
# AWSでパッシブモードにすると外部から接続できないので、外部向けのIPアドレスを設定する
# https://docs.microsoft.com/en-us/iis/configuration/system.applicationhost/sites/site/ftpserver/firewallsupport
cmd /c \Windows\System32\inetsrv\appcmd.exe set config -section:system.applicationHost/sites /siteDefaults.ftpServer.firewallSupport.externalIp4Address:$publicip /commit:apphost
# パッシブポートのレンジを制限
# https://docs.microsoft.com/en-us/iis/configuration/system.ftpserver/firewallsupport
cmd /c \Windows\System32\inetsrv\appcmd.exe set config -section:system.ftpServer/firewallSupport /lowDataChannelPort:"60000" /commit:apphost
cmd /c \Windows\System32\inetsrv\appcmd.exe set config -section:system.ftpServer/firewallSupport /highDataChannelPort:"65535" /commit:apphost
# サイトを再起動
# Restart-WebItem "IIS:\Sites\$ftpsite"
# サービスの再起動
Restart-Service ftpsvc
続いてFTP接続に使用するユーザを作成し、ホームディレクトリを用意する。
ついでにアクセス権を制限する。
# ユーザ名
$username = "FTPUSER"
# ランダムパスワードの生成
$number = 48..57
$upper = 65..90
$lower = 97..122
$password = (1..10 | foreach { $number + $upper + $lower | get-random } | foreach { [char]$_ }) -join ''
# パスワードの暗号化
$secure = $password | ConvertTo-SecureString -AsPlainText -Force
# ローカルユーザの追加
$user = New-LocalUser -PasswordNeverExpires -Name $username -Password $secure -Description "FTP User"
# パスワードの表示
Write-Host -ForegroundColor red $password
# グループの追加
Add-LocalGroupMember -Group "Users" -Member $user
# FTPUSERのホームディレクトリ
$dir = mkdir C:\inetpub\ftproot\LocalUser\$username
# ディレクトリのアクセスルールをすべて削除
icacls $dir /reset /q # 個別設定を破棄
icacls $dir /inheritance:r /q # 上位フォルダからの継承を破棄
# アクセス権を追加
icacls $dir /grant "administrators:(OI)(CI)F" /q
icacls $dir /grant "${username}:(OI)(CI)F" /q
# アクセス権を確認
icacls $dir
Set-Acl
は割とどうしようもなく使えない子なのですが、icacls
の構文すぐ忘れてしまうので ACL が一番思い出すのが大変です。