Настройка доступа к Jenkins через nginx
Некоторое время назад я настроил на своей домашней машине билд-сервер Jenkins для того, чтобы автоматизировать различные рутинные задачи, связанные с разработкой.
Довольно быстро обнаружилось, что, помимо прочего, мне удобно с его помощью собирать и несколько публичных проектов. Например, horta-hell и codingteam.org.ru. Коллеги-разработчики неоднократно просили меня выставить Jenkins наружу, что я в итоге и сделал.
Процесс не совсем тривиальный, так что я бы хотел поделиться результатами своих изысканий.
В первую очередь следует ограничить доступ к проектам на сервере только доверенными пользователями. Я также рекомендую отключать регистрацию и "регистрировать только по инвайтам". Для этого следует зайти в настройки безопасности (опция "Configure Global Security") и активировать режим "Project-based Matrix Authorization Strategy", после чего можно подробнейшим образом настроить доступы всем пользователям.
В настройках каждого проекта теперь можно включить галочку "Enable project-based security" и, например, дать анонимному пользователю право на просмотр информации о проекте.
Предоставлять доступ к Jenkins мы будем сразу по доменному имени на 80 порту, потому что jenkins.fornever.me — это намного круче, чем 192.168.1.100:8080/jenkins
. Общая схема будет такова: Jenkins отвечает по какому-то своему порту только своему компьютеру (т. е. localhost
), а nginx, который установлен на этой же машине, публикует доступ к Jenkins уже с нужными нам настройками. На этом же этапе можно добавить SSL, но этого в данной статье я делать не буду для упрощения изложения.
Для начала настроим сам Jenkins, чтобы он отвечал только нужному нам компьютеру. В общем случае для этого следует передать аргументы --httpPort
и --httpListenAddress
исполняемому файлу java
, который используется для запуска Jenkins.
Например, на Windows для этого следует отредактировать файл jenkins.xml
, который находится в том каталоге, куда был установлен Jenkins. В элемент <service>
следует добавить элемент <arguments>
(если его ещё нет) с примерно вот таким содержимым:
<arguments>-Xrs -Xmx256m -Dhudson.lifecycle=hudson.lifecycle.WindowsServiceLifecycle -jar "%BASE%\jenkins.war" --httpPort=3500 --httpListenAddress=127.0.0.1</arguments>
И теперь остаётся только обеспечить реверсивное проксирование. Вот релевантный отрывок из моего nginx.conf
:
server {
listen 80;
server_name jenkins.fornever.me;
location / {
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:4899;
}
location ~ ^/(people/) {
allow 127.0.0.1;
deny all;
}
location ~ ^/(asynchPeople/) {
allow 127.0.0.1;
deny all;
}
}
Хотелось бы отметить следующие моменты:
- если в строке
proxy_pass
оставить конечный слэш вот так:proxy_pass http://127.0.0.1:4899/;
— то Jenkins будет ругаться "It appears that your reverse proxy set up is broken". Чтобы победить эту проблему — не нужно ставить слэш в конце URL; - я решил заблокировать адреса
people
иasynchPeople
, т.к. они показывают списки всех коммитеров во все проекты, которые зарегистрированы на Jenkins, и создают этим некоторую брешь в безопасности.
Не стоит также забывать о том, что Jenkins самостоятельно свой URL определить не может, поэтому его следует задать в разделе конфигурации "Jenkins Location".
Вот таким нехитрым образом мы опубликовали свой локальный Jenkins для всех пользователей сети.