- PVSM.RU - https://www.pvsm.ru -
Мы продолжаем серию статей с практическими инструкциями о том, как облегчить жизнь эксплуатации и разработчикам в повседневной работе с Kubernetes. Все они собраны из нашего опыта решения задач от клиентов и со временем улучшались, но по-прежнему не претендуют на идеал — рассматривайте их скорее как идеи и заготовки, предлагайте свои решения и улучшения в комментариях.
На этот раз будут рассмотрены две темы, условно связанные одной темой: доступом пользователей к dev-окружению.
Перед нами часто стоит задача закрыть за basic auth или за белым списком весь dev-контур (десятки/сотни приложений), дабы туда не могли попасть поисковые боты или просто очень сторонние люди.
Обычно для ограничения доступов каждому Ingress и приложению надо создавать отдельные секреты basic auth [1]. Управлять ими очень проблематично, когда набирается с десяток приложений. Поэтому мы организовали централизованное управление доступами.
Для этого был создан nginx с конфигурацией такого типа:
location / {
satisfy any;
auth_basic "Authentication or whitelist!";
auth_basic_user_file /etc/nginx/htpasswd/htpasswd;
allow 10.0.0.0/8;
allow 175.28.12.2/32;
deny all;
try_files FAKE_NON_EXISTENT @return200;
}
location @return200 {
return 200 Ok;
}
Далее в Ingress'ах приложений мы просто добавляем аннотацию:
ingress.kubernetes.io/auth-url: "http://dev-auth.dev-auth-infra.svc.cluster.local"
Таким образом, при обращении к приложению запрос уходит в сервис dev-auth
, который проверяет, введен ли корректный basic auth или же клиент входит в whitelist. Если одно из условий выполнено, запрос подтверждается и проходит в приложение.
В случае использования такого сервиса достаточно одного репозитория, в котором хранится список всех доступов и через который мы можем удобно конфигурировать свой «единый центр авторизации». Его распространение на новые приложения производится элементарным добавлением аннотации.
… будь то Redis, RabbitMQ, PostgreSQL или любимый PHP-разработчиками Xdebug.
Очень часто, переводя приложения в Kubernetes, для обеспечения лучшей безопасности нам приходится закрывать доступ снаружи и вовсе. И тогда разработчики, которые привыкли «ходить своей IDE» в базу или в Xdebug, испытывают серьёзные трудности.
Для решения этой проблемы мы используем VPN прямо в кластере Kubernetes. Общая схема выглядит таким образом, что при подключении к VPN-серверу, запущенному в K8s, в конфигурационном файле OpenVPN мы push'им адрес DNS-сервера, который тоже живёт в K8s. OpenVPN конфигурирует VPN таким образом, что при запросе ресурса внутри Kubernetes он сначала попадает в DNS-сервер Kubernetes — например, за адресом сервиса redis.production.svc.cluster.local
. DNS в Kubernetes резолвит его в адрес 10.244.1.15 и запросы на этот IP-адрес идут через OpenVPN прямо в кластер Kubernetes.
За время эксплуатации этого решения мы успели его неоднократно расширить. В частности:
Получившаяся админка [3] (см. также на Docker Hub [4]) выглядит очень аскетично:
Можно заводить новых юзеров или отзывать старые сертификаты:
Также можно посмотреть конфиг для данного клиента:
Для этого мы написали Python-скрипт, который при подключении юзера к OpenVPN, используя логин и пароль, сравнивает хэш в базе GitLab и проверяет его статус (активен ли он).
Вот сам скрипт:
#!/usr/bin/env python3
# pip3 install psycopg2-binary bcrypt
import bcrypt
import sys
import os
import psycopg2
import yaml
with open("/etc/openvpn/setup/config.yaml", 'r') as ymlfile:
cfg = yaml.load(ymlfile)
def get_user_info(username=''):
try:
connect_str = "dbname=%s user=%s host=%s password=%s" % (cfg['db'], cfg['user'], cfg['host'], cfg['pass'])
# use our connection values to establish a connection
conn = psycopg2.connect(connect_str)
# create a psycopg2 cursor that can execute queries
cursor = conn.cursor()
# create a new table with a single column called "name"
cursor.execute("""SELECT encrypted_password,state FROM users WHERE username='%s';""" % username)
# run a SELECT statement - no data in there, but we can try it
rows = cursor.fetchall()
print(rows)
return(rows[0])
except Exception as e:
print("Uh oh, can't connect. Invalid dbname, user or password?")
print(e)
def check_user_auth():
username = os.environ['username']
password = bytes(os.environ['password'], 'utf-8')
# hashed = bcrypt.hashpw(password, bcrypt.gensalt())
user_info = get_user_info(username=username)
user_encrypted_password = bytes(user_info[0], 'utf-8')
user_state = True if user_info[1] == 'active' else False
if bcrypt.checkpw(password, user_encrypted_password) and user_state:
print("It matches!")
sys.exit(0)
else:
print("It does not match :(")
sys.exit(1)
def main():
check_user_auth()
if __name__ == '__main__':
main()
А в конфиге OpenVPN просто указываем следующее:
auth-user-pass-verify /etc/openvpn/auth-user.py via-env
script-security 3
client-cert-not-required
Таким образом, если у клиента увольнялся сотрудник, его просто деактивировали в GitLab, после чего он не сможет подключиться и к VPN'у.
В продолжении цикла статей с практическими рецептами компании «Флант» по эксплуатации Kubernetes я раскрою такие темы, как выделение отдельных узлов под конкретные задачи (зачем и как?) и настройка под большие нагрузки служб вроде php-fpm/gunicorn, запущенных в контейнерах. Подписывайтесь на наш блог, чтобы не пропускать обновления!
Другое из цикла K8s tips & tricks:
Читайте также в нашем блоге:
Автор: Андрей Сидоров
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/openvpn/297082
Ссылки в тексте:
[1] отдельные секреты basic auth: https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx/examples/auth
[2] официальный чарт: https://github.com/helm/charts/tree/master/stable/openvpn
[3] Получившаяся админка: https://github.com/vitaliy-sn/openvpn-easyrsa-web-ui/tree/dev
[4] Docker Hub: https://hub.docker.com/r/ixdx/openvpn-easyrsa-web-ui/
[5] Ускоряем bootstrap больших баз данных: https://habr.com/company/flant/blog/417509/
[6] 11 способов (не) стать жертвой взлома в Kubernetes: https://habr.com/company/flant/blog/417905/
[7] Сборка и дeплой приложений в Kubernetes с помощью dapp и GitLab CI: https://habr.com/company/flant/blog/345580/
[8] Мониторинг и Kubernetes: https://habr.com/company/flant/blog/412901/
[9] Наш опыт с Kubernetes в небольших проектах: https://habr.com/company/flant/blog/331188/
[10] Источник: https://habr.com/post/427745/?utm_source=habrahabr&utm_medium=rss&utm_campaign=427745
Нажмите здесь для печати.