Почему Jenkins на узле докера отвечает на HTTP-запросы из контейнеров?

Я испытываю довольно странное поведение на машине, на которой установлены Jenkins и Docker. Для ясности: Jenkins работает не как контейнер Docker, а под пользователем jenkins.

При запуске curl в контейнере я получаю 403:

root@ada71c8116bf:/# curl -I www.google.co.uk
HTTP/1.1 403 Forbidden
Date: Tue, 30 May 2017 13:41:07 GMT
X-Content-Type-Options: nosniff
Set-Cookie: JSESSIONID.f1223778=36hjq9sozhveoe1bfsss1dnq;Path=/;HttpOnly
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: text/html;charset=UTF-8
X-Hudson: 1.395
X-Jenkins: 2.46.3
X-Jenkins-Session: 2836b130
X-You-Are-Authenticated-As: anonymous
X-You-Are-In-Group-Disabled: JENKINS-39402: use -Dhudson.security.AccessDeniedException2.REPORT_GROUP_HEADERS=true or use /whoAmI to diagnose
X-Required-Permission: hudson.model.Hudson.Read
X-Permission-Implied-By: hudson.security.Permission.GenericRead
X-Permission-Implied-By: hudson.model.Hudson.Administer
Content-Length: 793
Server: Jetty(9.2.z-SNAPSHOT)

Вне контейнера на хосте я получаю ожидаемый ответ:

$ curl -I www.google.co.uk
HTTP/1.1 200 OK
Date: Tue, 30 May 2017 13:40:17 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
P3P: CP="This is not a P3P policy! See https://www.google.com/support/accounts/answer/151657?hl=en for more info."
Server: gws
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Set-Cookie: NID=104=mMKjBy002X3N_SkhkD_8xuAwpFuw03CFi0iOJjNX81FUHfMT6qTq95LcgRwdhrV_GZoUF9LQ1B9qAQPriN9Er3Bu2JWoqPgvt16TduuVj5QsNs9GiJTQBtaSXWic7G9E; expires=Wed, 29-Nov-2017 13:40:17 GMT; path=/; domain=.google.co.uk; HttpOnly
Transfer-Encoding: chunked
Accept-Ranges: none
Vary: Accept-Encoding

Jenkins, очевидно, виноват, но я понятия не имею, почему он будет перехватывать HTTP-трафик, покидающий контейнеры. Пинг Google работает нормально, так же как и отправка HTTPS-запросов. Никакая другая машина не имеет этой проблемы (предположительно, потому что на них не установлен Jenkins). Итак, что здесь происходит? Как заставить Jenkins прекратить перехват HTTP из контейнеров Docker?

Обновить

Отключение параметра Jenkins «Предотвратить подделку межсайтовых запросов» приводит к тому, что Jenkins больше не возвращает 403. Вместо этого Jenkins отвечает на любой HTTP-запрос из контейнера страницей панели мониторинга, то есть страницей по умолчанию.

Также стоит отметить, что DNS работает нормально; имена хостов разрешаются в правильные IP-адреса.

Я собираюсь выйти из Wireshark.


person Lukeus_Maximus    schedule 30.05.2017    source источник


Ответы (1)


С помощью Wireshark я обнаружил, что что-то перенаправляет HTTP-трафик на порт 8090 на хосте. Удачный поиск в Google привел меня к проверке таблиц IP-адресов хоста (iptables -t nat -L -n) и, конечно же, были правила, которые перенаправляли весь трафик порта 80 откуда на порт 8090 хоста. Кто-то явно настроил это перенаправление в интересах пользователей Jenkins.

Решение состояло в том, чтобы изменить таблицы IP, чтобы не перенаправлять трафик, поступающий из подсети докера.

Столы до:

$ sudo iptables -t nat -L -n 
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination              
REDIRECT   tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:80 redir ports 8090
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
REDIRECT   tcp  --  0.0.0.0/0            127.0.0.1            tcp dpt:80 redir ports 8090
DOCKER     all  --  0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0           

Chain DOCKER (2 references)
target     prot opt source               destination         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0   

Команды для изменения:

$ sudo iptables -t nat -R PREROUTING 1 ! -s 172.17.0.0/16 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8090
$ sudo iptables -t nat -R OUTPUT 1 ! -s 172.17.0.0/16 -d 127.0.0.1/32 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8090

Результирующие таблицы IP:

$ sudo iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
REDIRECT   tcp  -- !172.17.0.0/16        0.0.0.0/0            tcp dpt:80 redir ports 8090
DOCKER     all  --  0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
REDIRECT   tcp  -- !172.17.0.0/16        127.0.0.1            tcp dpt:80 redir ports 8090
DOCKER     all  --  0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0           

Chain DOCKER (2 references)
target     prot opt source               destination         
RETURN     all  --  0.0.0.0/0            0.0.0.0/0    
person Lukeus_Maximus    schedule 01.06.2017
comment
Вы не получили здесь много ответов, поэтому я хотел бы сказать, что ваш ответ уже дважды решил мою аналогичную проблему между сегодняшним днем ​​и моментом, когда вы его опубликовали. Спасибо! - person gleerman; 19.10.2018