Имеется VPN сервис, работающий в AWS на EC2, доступ к которому ограничен с помощью security group.
Задача: набросать скрипт, который работал бы под Linux/Windows (VPN-ом пользуюсь не я один), который позволял бы быстро добавить запись с новым IP для доступа.
Используем Python 3 и boto3.
Содержание
Зависимости
Первым делом — необходимо придумать как установить зависимости, в частности — библиотеку boto3, что бы упростить жизнь пользователю (хотя Python всё-равно придётся устанавливать вручную).
Добавляем функцию pip_install():
...
def pip_install(pkg_name):
pip.main(['install', pkg_name])
...
И её вызов, сейчас скрипт полностью выглядит так:
#!/usr/bin/env python
import sys
import pip
def pip_install(pkg_name):
pip.main(['install', pkg_name])
if __name__ == '__main__':
print('\nChecking for dependencies...')
try:
import boto3
print('boto3 library already installed - OK.\n')
except ImportError:
print('boto3 not found - going to install it now...\n')
pip_install('boto3')
print('\nDone - please, restart script nnow.\n')
exit(0)
Запускаем, проверяем:
[simterm]
$ ./aws_update_setevoy_vpn_sg.py Checking for dependencies... boto3 library already installed - OK.
[/simterm]
AWS IAM пользователь
Теперь, прежде чем продолжать — добавим отдельного пользователя, у которого будет доступ только к определённой security group.
Создаём новую IAM policy с правами DescribeSecurityGroups и AuthorizeSecurityGroupIngress:
Создаём пользователя с programmatic access (доступ в AWS Console ему совсем не нужен):
Подключаем ему созданную политику:
Проверяем доступ.
Задаём переменные для авторизации:
[simterm]
$ export AWS_ACCESS_KEY_ID=AKI***WNA
$ export AWS_SECRET_ACCESS_KEY=oaZ***uMW
[/simterm]
Пробуем получить список EC2 машин, к которому доступа мы не давали (DescribeInstances):
[simterm]
$ aws ec2 describe-instances An error occurred (UnauthorizedOperation) when calling the DescribeInstances operation: You are not authorized to perform this operation.
[/simterm]
Хорошо, и пробуем получить список групп безопасности — тут права заданы, доступ должен быть:
[simterm]
$ aws ec2 describe-security-groups --output text SECURITYGROUPS rtfm_prod_db_access sg-3e723c58 rtfm_prod_db_access 264418146286 vpc-3941cb5c IPPERMISSIONS 3306 tcp 3306 ...
[/simterm]
ОК, работает.
boto3
EC2 client
Теперь можно приступать к работе с ресурсами AWS.
Первым делом — создаём клиент — EC2.Client:
...
def create_conn(aws_access_key, aws_secret_key, ec2_region):
conn = boto3.client('ec2', aws_access_key_id=aws_access_key, aws_secret_access_key=aws_secret_key, region_name=ec2_region)
return conn
...
Добавляем вызов этой функции:
...
# create boto3 connection first
client = create_conn('AKI***EZQ', '+HKp***k1P', 'eu-west-1')
Добавление rule
Добавляем ещё одну функцию add_rule(), в которой вызываем метод authorize_security_group_ingress() из объекта client:
...
def add_rule(client, sg_id, cidr):
client.authorize_security_group_ingress(GroupId=sg_id, IpProtocol='udp',CidrIp=cidr,FromPort=1194,ToPort=1194)
И добавляем запуск всего, теперь скрипт полностью выглядит так:
#!/usr/bin/env python
import sys
import pip
def pip_install(pkg_name):
pip.main(['install', pkg_name])
def create_conn(aws_access_key, aws_secret_key, ec2_region):
conn = boto3.client('ec2', aws_access_key_id=aws_access_key, aws_secret_access_key=aws_secret_key, region_name=ec2_region)
return conn
def add_rule(client, sg_id, cidr):
client.authorize_security_group_ingress(GroupId=sg_id, IpProtocol='udp',CidrIp=cidr,FromPort=1194,ToPort=1194)
if __name__ == '__main__':
# check for first argument
assert(len(sys.argv) == 2)
print('\nChecking for dependencies...')
try:
import boto3
print('boto3 library already installed - OK.\n')
except ImportError:
print('boto3 not found - going to install it now...\n')
pip_install('boto3')
print('\nDone - please, restart script nnow.\n')
exit(0)
# add /32 mask to an IP
cidr = sys.argv[1] + '/32'
# vars
aws_access_key = 'AKI***WNA'
aws_secret_key = 'oaZ***uMW'
ec2_region = 'eu-west-1'
sg_id = 'sg-7cdef305'
# create boto3 connection first
print('Creating connection...')
client = create_conn(aws_access_key, aws_secret_key, ec2_region)
# add new rule with IP from first arg
print('Adding new rule with IP {}...'.format(cidr))
add_rule(client, sg_id, cidr)
print('\nDone.\n')
Запускаем:
[simterm]
$ ./aws_update_setevoy_vpn_sg.py 0.0.0.0 Checking for dependencies... boto3 library already installed - OK. Creating connection... Adding new rule with IP 0.0.0.0/32... Done.
[/simterm]
Проверяем:
[simterm]
$ aws ec2 describe-security-groups --group-ids sg-7cdef305 --output text ... IPPERMISSIONS 1194 udp 1194 ... IPRANGES 0.0.0.0/32
[/simterm]
Готово:
ToDoBetter
Что хорошо было бы добавить в этот скрипт — это:
- авторизация — было бы правильнее реализовать через
~/.aws/credentialsили через переменные окружения (см. тут>>>), а не хардкодить прямо в скрипт, но т.к. на машине пользователя AWS CLI нет, а рассказывать как в Windows добавить переменные — не хочется, то передаём так; - удаление старого правила — но тут надо сделать выборку по полю Description каждого правила, а в
boto3я такой возможности не нашёл; - добавить описание для добавляемого правила, но опять-таки — см. п. 1.





