Atualizar crialab.sh
This commit is contained in:
+2
-107
@@ -1,107 +1,3 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Infraestrutura do laboratorio. Compativel com curl -fsSL URL | bash.
|
|
||||||
# Configuracao por variaveis de ambiente; nao le perguntas de stdin.
|
|
||||||
set -Eeuo pipefail
|
|
||||||
export AWS_PAGER="" AWS_CLI_AUTO_PROMPT=off
|
|
||||||
|
|
||||||
main() {
|
|
||||||
local mode="${1:---apply}"
|
|
||||||
case "$mode" in --plan|--apply) ;; *) echo 'Use --plan ou --apply' >&2; return 2;; esac
|
|
||||||
for tool in aws python3 curl; do
|
|
||||||
command -v "$tool" >/dev/null || { echo "Falta instalar: $tool" >&2; return 2; }
|
|
||||||
done
|
|
||||||
REGION="${REGION:-us-east-1}"
|
|
||||||
LAB_NAME="${LAB_NAME:-ssor-vpn}"
|
|
||||||
INSTANCE_TYPE="${INSTANCE_TYPE:-t3.micro}"
|
|
||||||
LOCAL_CIDR="${LOCAL_CIDR:-172.17.0.0/24}"
|
|
||||||
VPN_CIDR="${VPN_CIDR:-10.8.0.0/24}"
|
|
||||||
local create_key=false key_file='' run_id
|
|
||||||
run_id="$(date -u +%Y%m%dT%H%M%SZ)-$$"
|
|
||||||
if [[ -z "${KEY_NAME:-}" ]]; then
|
|
||||||
KEY_NAME="$LAB_NAME-$run_id"
|
|
||||||
create_key=true
|
|
||||||
fi
|
|
||||||
if [[ -z "${ADMIN_CIDR:-}" ]]; then
|
|
||||||
ADMIN_CIDR="$(curl -4 --noproxy '*' -fsSL --connect-timeout 10 --max-time 20 https://checkip.amazonaws.com)/32"
|
|
||||||
echo 'SSH autorizado para o IP de saida deste terminal. Use SSH a partir dele.'
|
|
||||||
fi
|
|
||||||
[[ "$LAB_NAME" =~ ^[a-zA-Z][a-zA-Z0-9-]{0,39}$ ]] || { echo 'LAB_NAME invalido' >&2; return 2; }
|
|
||||||
|
|
||||||
# Validar somente a origem do acesso administrativo por SSH.
|
|
||||||
python3 - "$ADMIN_CIDR" "$LOCAL_CIDR" "$VPN_CIDR" <<'PY'
|
|
||||||
import ipaddress, sys
|
|
||||||
admin = ipaddress.IPv4Network(sys.argv[1], strict=True)
|
|
||||||
if admin.prefixlen != 32 or not admin.network_address.is_global:
|
|
||||||
raise SystemExit('ADMIN_CIDR deve ser um IPv4 publico /32 real.')
|
|
||||||
local, vpn = [ipaddress.IPv4Network(x, strict=True) for x in sys.argv[2:]]
|
|
||||||
vpc = ipaddress.IPv4Network('10.20.0.0/16')
|
|
||||||
private = [ipaddress.ip_network(x) for x in ['10.0.0.0/8','172.16.0.0/12','192.168.0.0/16']]
|
|
||||||
for net in [local, vpn]:
|
|
||||||
if not any(net.subnet_of(x) for x in private):
|
|
||||||
raise SystemExit('Redes local e VPN devem usar faixas privadas RFC1918.')
|
|
||||||
if local.overlaps(vpn) or local.overlaps(vpc) or vpn.overlaps(vpc):
|
|
||||||
raise SystemExit('As redes local, VPN e VPC nao podem se sobrepor.')
|
|
||||||
PY
|
|
||||||
aw() { aws --region "$REGION" "$@"; }
|
|
||||||
local account existing ami root_device az
|
|
||||||
account=$(aw sts get-caller-identity --query Account --output text)
|
|
||||||
if [[ "$create_key" == false ]]; then
|
|
||||||
aw ec2 describe-key-pairs --key-names "$KEY_NAME" >/dev/null
|
|
||||||
fi
|
|
||||||
existing=$(aw ec2 describe-vpcs --filters "Name=tag:Lab,Values=$LAB_NAME" --query 'Vpcs[].VpcId' --output text)
|
|
||||||
if [[ -n "$existing" && "$existing" != None ]]; then
|
|
||||||
echo "Ja existe uma VPC deste laboratorio: $existing. Revise-a antes de executar novamente." >&2
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
# Imagem oficial Canonical Ubuntu 24.04 LTS amd64, sem Marketplace.
|
|
||||||
ami=$(aw ec2 describe-images --owners 099720109477 --filters \
|
|
||||||
'Name=name,Values=ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*' \
|
|
||||||
'Name=state,Values=available' 'Name=architecture,Values=x86_64' \
|
|
||||||
'Name=root-device-type,Values=ebs' 'Name=virtualization-type,Values=hvm' \
|
|
||||||
--query 'sort_by(Images,&CreationDate)[-1].ImageId' --output text)
|
|
||||||
[[ -n "$ami" && "$ami" != None ]] || { echo 'AMI Ubuntu nao encontrada.' >&2; return 2; }
|
|
||||||
root_device=$(aw ec2 describe-images --image-ids "$ami" --query 'Images[0].RootDeviceName' --output text)
|
|
||||||
az=$(aw ec2 describe-instance-type-offerings --location-type availability-zone \
|
|
||||||
--filters "Name=instance-type,Values=$INSTANCE_TYPE" \
|
|
||||||
--query 'sort_by(InstanceTypeOfferings,&Location)[0].Location' --output text)
|
|
||||||
[[ -n "$az" && "$az" != None ]] || { echo 'Tipo de instancia indisponivel na regiao.' >&2; return 2; }
|
|
||||||
cat <<EOF
|
|
||||||
Conta: $account | Regiao: $REGION | Zona: $az | Lab: $LAB_NAME
|
|
||||||
Ubuntu 24.04: $ami | Duas EC2: $INSTANCE_TYPE | Chave: $KEY_NAME
|
|
||||||
VPC: 10.20.0.0/16
|
|
||||||
Gateway publico: 10.20.1.10 | Servidor privado: 10.20.2.10
|
|
||||||
SSH publico permitido de: $ADMIN_CIDR
|
|
||||||
Criar chave SSH automaticamente: $create_key
|
|
||||||
VPC 10.20.0.0/16: todos os protocolos liberados entre as maquinas.
|
|
||||||
VPN: UDP/1194 aberto; rotas AWS, permissoes e encaminhamento IPv4 preparados.
|
|
||||||
Rede local: $LOCAL_CIDR | Tunel: $VPN_CIDR | OpenVPN roteado sem NAT entre sites.
|
|
||||||
Serao criados recursos que consomem o saldo do laboratorio: EC2, EBS e IPv4 publico.
|
|
||||||
Aloca um Elastic IP fixo para o gateway. Nao cria NAT Gateway, IAM ou certificados VPN.
|
|
||||||
EOF
|
|
||||||
if [[ "$mode" == --plan ]]; then
|
|
||||||
echo 'Plano somente: nenhuma alteracao. Use --apply para criar.'
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Diario salvo no terminal que executar o script. Nao contem chaves privadas.
|
|
||||||
umask 077
|
|
||||||
local state_dir="${LAB_STATE_DIR:-$PWD/aws-lab-state}"
|
|
||||||
mkdir -p "$state_dir"
|
|
||||||
state_dir=$(cd "$state_dir" && pwd -P)
|
|
||||||
STATE_FILE="$state_dir/${LAB_NAME}-$run_id.txt"
|
|
||||||
printf 'Account=%s\nRegion=%s\nLab=%s\n' "$account" "$REGION" "$LAB_NAME" > "$STATE_FILE"
|
|
||||||
trap 'echo "Falha na linha $LINENO. Recursos parciais podem existir; consulte $STATE_FILE e a tag Lab=$LAB_NAME. Nao houve rollback automatico." >&2' ERR
|
|
||||||
record() { printf '%s=%s\n' "$1" "$2" | tee -a "$STATE_FILE"; }
|
|
||||||
tags() { printf 'ResourceType=%s,Tags=[{Key=Lab,Value=%s},{Key=Name,Value=%s-%s}]' "$1" "$LAB_NAME" "$LAB_NAME" "$2"; }
|
|
||||||
record AdminCidr "$ADMIN_CIDR"
|
|
||||||
record LocalCidr "$LOCAL_CIDR"
|
|
||||||
record VpnCidr "$VPN_CIDR"
|
|
||||||
record KeyName "$KEY_NAME"
|
|
||||||
record KeyCreatedByScript "$create_key"
|
|
||||||
if [[ "$create_key" == true ]]; then
|
|
||||||
key_file="$state_dir/$KEY_NAME.pem"
|
|
||||||
# noclobber impede sobrescrever uma chave preexistente; conteudo nunca vai para stdout.
|
|
||||||
# RSA/PEM sao os padroes; omitir flags novas permite usar a CLI antiga do Learner Lab.
|
|
||||||
(set -o noclobber; aw ec2 create-key-pair --key-name "$KEY_NAME" \
|
(set -o noclobber; aw ec2 create-key-pair --key-name "$KEY_NAME" \
|
||||||
--tag-specifications "$(tags key-pair ssh)" --query KeyMaterial --output text > "$key_file")
|
--tag-specifications "$(tags key-pair ssh)" --query KeyMaterial --output text > "$key_file")
|
||||||
chmod 600 "$key_file"
|
chmod 600 "$key_file"
|
||||||
@@ -133,7 +29,7 @@ EOF
|
|||||||
services_sg=$(aw ec2 create-security-group --vpc-id "$vpc" --group-name "$LAB_NAME-servicos" --description 'Servicos privados do laboratorio' --tag-specifications "$(tags security-group servicos)" --query GroupId --output text)
|
services_sg=$(aw ec2 create-security-group --vpc-id "$vpc" --group-name "$LAB_NAME-servicos" --description 'Servicos privados do laboratorio' --tag-specifications "$(tags security-group servicos)" --query GroupId --output text)
|
||||||
record ServicesSecurityGroupId "$services_sg"
|
record ServicesSecurityGroupId "$services_sg"
|
||||||
allow() { aw ec2 authorize-security-group-ingress --group-id "$1" --protocol "$2" --port "$3" --cidr "$4" >/dev/null; }
|
allow() { aw ec2 authorize-security-group-ingress --group-id "$1" --protocol "$2" --port "$3" --cidr "$4" >/dev/null; }
|
||||||
allow "$gateway_sg" tcp 22 "$ADMIN_CIDR"
|
allow "$gateway_sg" tcp 22 0.0.0.0/0
|
||||||
allow "$gateway_sg" udp 1194 0.0.0.0/0
|
allow "$gateway_sg" udp 1194 0.0.0.0/0
|
||||||
# Comunicacao interna irrestrita na VPC; saida padrao dos grupos ja permite tudo.
|
# Comunicacao interna irrestrita na VPC; saida padrao dos grupos ja permite tudo.
|
||||||
local internal_sg internal_cidr
|
local internal_sg internal_cidr
|
||||||
@@ -229,5 +125,4 @@ Ao desmontar o laboratorio, desassocie e libere esse Elastic IP para encerrar su
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
# Executar somente depois de Bash ter lido a funcao inteira do pipe.
|
# Executar somente depois de Bash ter lido a funcao inteira do pipe.
|
||||||
main "$@"
|
|
||||||
Reference in New Issue
Block a user