Traefik — 3. защищаем админку сайта
4 июля 2023
Изучая документацию Traefik наткнулся на интересную возможность назначать правила совпадения роутеров не только по имени домена, но и по части URL. Эту особенность можно попробовать использовать для защиты админки сайта.
Допустим, у нас есть сайт (или какой-либо сервис), доступный большей части пользователей. Но зачем светить админкой на весь мир? Можно её сделать доступной только из нашей страны.
В статье про установку Traefik я расписывал конфигурацию при которой правило маршрутизации сопоставлялось только по доменному имени с помощью оператора Host. Для проверки по пути URL существует также оператор Path. Синтаксис из документации:
Path(`/path`, `/articles/{cat:[a-z]+}/{id:[0-9]+}`, ...)
Как видите, поддерживаются, в том числе, и регулярные выражения.
Рассмотрим случай, когда у нас есть сайт example.com и его админка располагается по адресу example.com/admin.php. Нам необходимо будет создать два правила: одно для админки, второе — для всего остального содержимого сайта. Выглядеть в файле конфигурации это будет следующим образом (вспоминаем статью о блокировках по странам):
http: routers: example-ssl: entryPoints: - https service: web-server1 middlewares: - "my-geoblock" rule: (Host(`example.com`) || Host(`www.example.com`)) && !Path(`/admin.php`) tls: certResolver: letsEncrypt example-ssl-admin: entryPoints: - https service: web-server1 middlewares: - "admin-geoblock" rule: (Host(`example.com`) || Host(`www.example.com`)) && Path(`/admin.php`) tls: certResolver: letsEncrypt
В роутере example-ssl мы с помощью модификатора my-geoblock будем блокировать доступ к основной части сайта. А вот в роутере example-ssl-admin блокируем (с помощью admin-geoblock) доступ уже к админке. Соответственно настройка middleware admin-geoblock будет выглядеть примерно так:
http: middlewares: admin-geoblock: plugin: geoblock: allowLocalRequests: "true" allowUnknownCountries: "false" api: https://get.geojs.io/v1/ip/country/{ip} apiTimeoutMs: "750" cacheSize: "15" blackListMode: false countries: - RU forceMonthlyUpdate: "true" logAllowedRequests: "false" logApiRequests: "true" logLocalRequests: "false" unknownCountryApiResponse: nil
В данном случае доступ к admin.php будет только с IP-адресов России.
