Google аутентификация на OAuth2_Proxy

Установка и настройка Reverse Proxy OAuth2_proxy. Пригодится например для защиты самописных ресурсов или других, которые не поддерживают механизмы аутентификации.

Установка

Устанавливаем GoLang, настраиваем переменные окружения и ставим OAuth2_proxy:

$ yum install golang
$ cat /etc/profile.d/go.sh:
#!/bin/bash
export GOPATH=/usr/share/gocode
export GOROOT=/usr/lib/golang

$ chmod +x /etc/profile.d/go.sh
$ source /etc/profile.d/go.sh
$ go -v get github.com/bitly/oauth2_proxy
$ ln -s /usr/share/gocode/bin/oauth2_proxy /usr/bin

Настройка аутентификации

Идем на: https://developers.google.com -> Google API Console. В диспетчере Google APIs в верхнем левом углу нажимаем на «Project -> создать проект». Вводим название проекта и жмем «создать». Далее там же выбираем уже созданный проект. Идем в меню «Учетные данные -> Создать учетные данные -> Идентификатор клиента OAuth -> Тип приложения Веб-Приложение». Далее выбираем созданную учетку и вводим название (пусть будет mysite). Разрешенные источники JavaScript: https://mysite.example.com.
Разрешенные URI перенаправления: https://mysite.example.com/oauth2/callback (по моему oauth2/callback может быть произвольной записью т.е. можно написать при желании хоть https://mysite.example.com/chupakabra). Снова переходим в «Учетные данные» и выбираем пункт «Окно запроса доступа OAuth», где вводим название продукта mysite и url главной страницы https://mysite.example.com (тогда после авторизации нас редиректит на этот url). Название продукта будет высвечиваться на этапе когда приложение запросит доступ при аутентификации.

Настройка OAuth2_proxy

Накидаем файл конфигурации:

$ mkdir /etc/oauth2_proxy
$ cat /etc/oauth2_proxy/mysite.cfg:

#слушаем localhost интерфейс на порту 4180
http_address = "127.0.0.1:4180"
#собственно та ссылку которую указывали в разрешенные uri перенаправления
redirect_url = "https://mysite.example.com/oauth2/callback"
upstreams = [
#тут пишем на какой хост перенаправлять запросы после успешной аутентификации (предположим что бекенд работает без ssl)
#адрес бекенда указать в /etc/hosts (зависит от того как у вас настроен dns)
"http://mysite.example.com"
]
#если true то будет сливать лог прямо в stdout (т.е. в терминал)
request_logging = true
#если раскоментируете эти строки то доступ получат все пользователи которые зарегистрированы в домене gmail.com
#email_domains = [
# "gmail.com"
#]
#список тех аккаунтов которые могут получить доступ
authenticated_emails_file = "/etc/oauth2_proxy/mysite.txt"
#идентификатор клиента (указан в учетных данных)
client_id = "xxxxxxxxxxxxxxxxx"
#секрет клиента (указан в учетных данных)
client_secret = "xxxxxxxxxxxxxxxxx"
#собственно провайдер oauth2
provider="google"
#название кукиса
cookie_name = "mysite.example.com"
#ключ шифрования кукиса (сгенерируйте произвольный пароль)
cookie_secret = "xxxxxxxxxxxxxxxxx"
#домен кукиса
cookie_domain = "example.com"
#время жизни кукиса
cookie_expire = "168h0m0s"
#если ресурс доступен по https то обязательно true если нет то false
cookie_secure = true
#если ресурс доступен по https то обязательно true если нет то false
cookie_httponly = true
#скрываем информацию о верссии программы с футера
footer = "-"
#по идее если true то сразу должен загрузится список аккаунтов вместо того чтобы показывать кнопку sign in with google но видимо не работает
skip-provider-button = true

Создаем список аккаунтов: echo -e «myfriend@gmail.com\nmyfriend2@gmail.com» >> /etc/oauth2_proxy/mysite.txt. Накидаем какой нить такой скрипт запуска /root/bin/oauth2_proxy.sh:

#!/bin/bash

CFG="mysite.cfg"
CFG_PATH="/etc/oauth2_proxy"
PID_FILE="mysite_oauth2.pid"
PID_PATH="/var/run"

function start {
        oauth2_proxy --config=$CFG_PATH/$CFG &
        ps -ef|grep $CFG|head -n1|awk '{print $2}' > $PID_PATH/$PID_FILE
}

function stop {
        if [ -f "$PID_PATH/$PID_FILE" ]; then
                PID=`cat $PID_PATH/$PID_FILE`
        else
                echo "$PID_PATH/$PID_FILE doesn't exist"
                exit 0
        fi
        if [ -z "$PID" ]; then
                echo "$PID empty"
                exit 0
        fi
        kill -9 $PID
        echo -n > $PID_PATH/$PID_FILE
}

function status {
        PID=`cat $PID_PATH/$PID_FILE`
        if [ ! -z "$PID" ]; then
                echo "Running..."
        else
                echo "Not running"
        fi
}

case "$1" in
        start)
                start
                ;;
        stop)
                stop
                ;;
        status)
                status
                ;;
        restart)
                stop
                sleep 1
                start
                ;;
        *)
                echo $"Usage: $0 {start|stop|status|restart}"
                ;;
esac

Настройка NGINX

server {
	listen 80;
	server_name mysite.example.com;
	rewrite ^(.*) https://$host$1;
	server_tokens off;
}

server {
	listen 443 ssl;
	ssl on;
	ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
	ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA256:ECDHE-ECDSA-AES256-SHA256:ECDHE-RSA-AES256-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA256:DHE-RSA-AES256-SHA256:AES256-GCM-SHA384:AES256-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:DES-CBC3-SHA:!RC4:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS';
	ssl_prefer_server_ciphers on;
	ssl_session_cache shared:SSL:10m;
	ssl_session_timeout 10m;
	ssl_certificate /etc/letsencrypt/live/mysite.example.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/mysite.example.com/privkey.pem;
	server_name mysite.example.com;
	server_tokens off;
	add_header Strict-Transport-Security max-age=2592000;
	access_log /usr/local/nginx/logs/mysite_access.log main;
	error_log /usr/local/nginx/logs/mysite_error.log;
	location / {
		proxy_pass http://127.0.0.1:4180;
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Scheme $scheme;
	}
	location ^~ /.well-known {
		alias /var/www/html/.well-known;
		charset off;
		add_header Content-Type text/plain;
	}
}

Теперь если зайти на https://mysite.example.com, то нас встретит унылая кнопочка.

Можете также почитать довольно полезную статью про сборку веб-сервера NGINX.

Порт старой статьи.