Установка Java
1 |
# apt-get update && apt-get install default-jdk |
1 |
# update-alternatives --config java |
1 2 |
There is only one alternative in link group java (providing /usr/bin/java): /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java Nothing to configure. |
1 |
# nano /etc/environment |
1 |
JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64" |
1 |
# source /etc/environment |
1 |
# echo $JAVA_HOME |
1 |
/usr/lib/jvm/java-8-openjdk-amd64 |
Установка Nexus
1 |
# wget http://download.sonatype.com/nexus/3/latest-unix.tar.gz |
1 |
# tar xvf latest-unix.tar.gz -C /opt/ |
1 |
# ln -s /opt/nexus-* /opt/nexus |
1 |
# useradd -m -r -s /bin/false nexus |
1 |
# chown -R nexus:nexus /opt/nexus-* /opt/sonatype-work /opt/nexus |
1 |
# nano /opt/nexus/bin/nexus.rc |
1 |
run_as_user="nexus" |
1 |
# nano /etc/systemd/system/nexus.service |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[Unit] Description=nexus service After=network.target [Service] Type=forking ExecStart=/opt/nexus/bin/nexus start ExecStop=/opt/nexus/bin/nexus stop User=nexus Restart=on-abort [Install] WantedBy=multi-user.target |
1 |
# systemctl daemon-reload && systemctl enable nexus |
1 |
# systemctl start nexus && systemctl status nexus |
Логи смотрим в
1 |
# tail -f /opt/sonatype-work/nexus3/log/*.log |
Настройка ротации логов Nexus
1 |
# cat /etc/logrotate.d/nexus |
1 2 3 4 5 6 7 8 9 10 |
/opt/sonatype-work/nexus3/log/*.log { daily dateext copytruncate missingok rotate 3 compress delaycompress notifempty } |
Установка Nginx
1 |
# wget -q -O - https://nginx.org/keys/nginx_signing.key | apt-key add - |
1 |
# nano /etc/apt/sources.list.d/nginx.list |
1 2 |
deb http://nginx.org/packages/ubuntu/ xenial nginx deb-src http://nginx.org/packages/ubuntu/ xenial nginx |
1 |
# apt-get update && apt-get install nginx |
1 |
# systemctl enable nginx && systemctl start nginx |
Настройка проксирования Nginx на Nexus
1 |
# nano /etc/nginx/conf.d/nexus.mydomain.com.conf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
upstream nexus_server { server 127.0.0.1:8081 fail_timeout=0; } server { listen 80; server_name nexus.mydomain.com www.nexus.mydomain.com; error_log /var/log/nginx/nexus-error.log; access_log /var/log/nginx/nexus-access.log main; location / { proxy_redirect off; proxy_pass http://nexus_server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 90; } } |
1 |
# nano /etc/nginx/ssl.conf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
ssl_session_cache shared:SSL:20m; ssl_session_timeout 1d; ssl_prefer_server_ciphers on; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; ssl_dhparam /etc/nginx/ssl/dhparam.pem; # ssl_ecdh_curve secp521r1; ## Improves TTFB by using a smaller SSL buffer than the nginx default ssl_buffer_size 8k; ## Enables OCSP stapling ssl_stapling on; resolver 8.8.8.8; ssl_stapling_verify on; ## Send header to tell the browser to prefer https to http #add_header Strict-Transport-Security max-age=31536000; |
1 |
# openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048 |
1 |
# nginx -t && service nginx reload |
Перевод Nexus на localhost
1 |
# cp /opt/sonatype-work/nexus3/etc/nexus.properties /opt/sonatype-work/nexus3/etc/nexus.properties~ |
1 |
# nano /opt/sonatype-work/nexus3/etc/nexus.properties |
1 |
application-host=127.0.0.1 |
1 |
# systemctl restart nexus && systemctl status nexus |
1 |
# netstat -nlptu | grep 8081 |
Логи смотрим
1 |
# tail -f /opt/sonatype-work/nexus3/log/*.log |
1 |
# netstat -nlptu | grep 8081 |
1 |
tcp 0 0 127.0.0.1:8081 0.0.0.0:* LISTEN 17562/java |
Настройка поддержки SSL
Установка Certbot
1 |
# apt-get update |
1 |
# apt-get install software-properties-common |
1 |
# add-apt-repository ppa:certbot/certbot |
1 |
# apt-get update |
1 |
# apt-get install python-certbot-nginx |
Получение SSL-сертификата
1 |
# certbot certonly --nginx -d nexus.mydomain.com -d www.nexus.mydomain.com --non-interactive --agree-tos --email user@mydomain.com |
Настройка SSL-поддержки в виртуальным хосте Nginx для Nexus
1 |
# nano /etc/nginx/conf.d/nexus.mydomain.com.conf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
upstream nexus_server { server 127.0.0.1:8081 fail_timeout=0; } server { listen 80; server_name nexus.mydomain.com www.nexus.mydomain.com; return 301 https://$host$request_uri; } server { listen 443 ssl http2; server_name nexus.mydomain.com www.nexus.mydomain.com; ssl_certificate /etc/letsencrypt/live/nexus.mydomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/nexus.mydomain.com/privkey.pem; include /etc/nginx/ssl.conf; error_log /var/log/nginx/nexus-error.log; access_log /var/log/nginx/nexus-access.log main; location / { proxy_redirect off; proxy_pass http://nexus_server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 90; } } |
1 |
# nginx -t && service nginx reload |
Настройка автопродления сертификатов
1 |
# crontab -e |
1 2 |
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 05 3 1 * * /usr/bin/certbot renew --force-renewal >> /var/log/letsencrypt/mydomain.com-renew.log 2>&1 |
Настройка Nexus-сервера
Для аутентифкаиции в WEB-интерфейсе используется логин/пароль admin/admin123
1 2 |
1.Изменить дефолтный пароль администратора(admin123) 2.Administration→Anonymous→Снять галку «Allow anonymous users to access the server»→Save |
Общий подход по доступу к менеджеру репозитариев Nexus состоит в установке перед Nexus обратного прокси-сервера,который принимает HTTPS-запросы от клиента, обрабатывая SSL/TLS соединение с клиентом, терминирует SSL/TLS и уже HTTP запрос отправляет на Nexus, после чего получает HTTP-ответ от Nexus пересылает его через HTTPS непосредственно клиенту
Альтернатитвным вариантом может быть непосредственная настройка Nexus-сервера на поддержку SSL/TLS средствами самого Nexus-сервера(без использования обратного прокси-сервера вообще)
https://help.sonatype.com/repomanager3/security/configuring-ssl#ConfiguringSSL-InboundSSL-ConfiguringtoServeContentviaHTTPS
В данном случае рассмотрим вариант с использованием Nginx в качестве обратного прокси-сервера(SSL/TLS-терминатора)
Cоздадим в Nexus Docker-репозитарий и получим к нему доступ
1 2 |
а) через SSL/TLS-соединение (с помощью Nginx-проксирования) б) без SSL/TLS-соединения (напрямую подключаясь к порту, на котором запущен Docker-репозитарий) |
Создание Docker-репозитария и пользователя с доступом к этому репозитарию
В WEB-интерфейсе Nexus создаем
а) репозитарий Docker (hosted)
1 2 3 |
Name→my-docker-repo Repository Connectors->HTTP→8082 Hosted→Allow redeploy |
Остальные параметры оставляем по умолчанию
б) пользователя
1 2 |
Login: my-docker-user Password: my-docker-password |
Рассмотрим первый вариант доступа в Docker-репозитарий через SSL/TLS-соединение (с помощью Nginx-проксирования)
1 |
client(HTTPS)→Nginx(HTTPS)→Docker repo(HTTP) на порт 8082->Nginx(HTTP)->Nginx(HTTS)->client |
Получение сертификата и настройка вирт.хоста Nginx для Docker-репозитария
В Nginx будет использоваться отдельный вирт.хост docker.mydomain.com для перенаправления запросов на Docker-репозитарий
т.к. Nexus был переведен нами на прослушивание запросов только на localhost, то порт Docker-репозитария(8082) также будет доступен только на localhost
Нас это устраивает т.к. мы будем проксировать на него запросы с Nginx,который также лоакально установлен на сервере с Nexus.
Получение сертификата для докер.вирт. хоста в Nginx(docker.mydomain.com)
1 |
# certbot certonly --nginx -d docker.mydomain.com -d www.docker.mydomain.com --non-interactive --agree-tos --email user@mydomain.com |
Настройка вирт.хоста Nginx для Docker-репозитария
1 |
# cp /etc/nginx/conf.d/nexus.mydomain.com.conf /etc/nginx/conf.d/docker.mydomain.com.conf |
Запросы проксируем на порт,указанный при создании Docker-репозитария(8082)
1 |
# nano /etc/nginx/conf.d/docker.mydomain.com.conf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
upstream docker_server { server 127.0.0.1:8082 fail_timeout=0; } server { listen 80; server_name docker.mydomain.com www.docker.mydomain.com; return 301 https://$host$request_uri; } server { listen 443 ssl http2; server_name docker.mydomain.com www.docker.mydomain.com; ssl_certificate /etc/letsencrypt/live/docker.mydomain.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/docker.mydomain.com/privkey.pem; include /etc/nginx/ssl.conf; error_log /var/log/nginx/docker-error.log; access_log /var/log/nginx/docker-access.log main; location / { proxy_redirect off; proxy_pass http://docker_server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_read_timeout 90; } } |
1 |
# nginx -t && service nginx reload |
Проверка доступности Docker-репозитария
1 |
# curl -X GET https://my-docker-user:my-docker-password@docker.mydomain.com/v2/_catalog |
1 |
{"repositories":[]} |
Подключаемся к Docker-репозитарию
1 |
# docker login docker.mydomain.com |
1 2 |
Username: my-docker-user Password: |
1 2 3 4 5 |
WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded |
Как видно из листинга, доступы к репозитарию сохраняются в файле
1 |
~/.docker/config.json |
и они будут использоваться при последующих подключениях к указанному репозитарию docker.mydomain.com
Рассмотрим второй вариант доступа в Docker-репозитарий (без SSL/TLS-соединения(как на стороне прокси-сервера, так и средствами самого Nexus-репозитария), напрямую подключаясь к порту, на котором запущен Docker-репозитарий)
1 |
client(HTTP)->Docker repo(HTTP) на порт 8082->client(HTTP) |
1. Разрешить в файрволле порт 8082(на который настроен/создан коннектор при создании репозитария Docker в Nexus)
1 |
# iptables -S | grep 8082 |
1 |
-A INPUT -p tcp -m tcp --dport 8082 -j ACCEPT |
2.Проверить/настроить Nexus на прослушивание запросов на всех интерфейсах(это настройка по умолчанию)(если перенастраивали Nexus на localhost, то перенастроить назад(просто закомментировать строку application-host=127.0.0.1 в файле /opt/sonatype-work/nexus3/etc/nexus.properties)
1 |
# netstat -nlptu | grep 8082 |
1 |
tcp 0 0 0.0.0.0:8082 0.0.0.0:* LISTEN 26916/java |
3.Перезапустить Nexus(если изменяли файл /opt/sonatype-work/nexus3/etc/nexus.properties)
1 |
# systemctl restart nexus |
Подключаться будем к Docker-репозитарию по имени Nexus-сервера(nexus.mydomain.com) на порт Docker-репозитария(8082)
Проверка доступности Docker-репозитария (порт 8082, имя сервера nexus.mydomain.com)
1 |
# curl -X GET http://my-docker-user:my-docker-password@nexus.mydomain.com:8082/v2/_catalog |
1 |
{"repositories":[]} |
Попытка залогиниться на Docker-репозитарий, который не поддерживает HTTPS
1 |
# docker login nexus.mydomain.com:8082 |
1 2 |
Username: my-docker-user Password: |
1 |
Error response from daemon: Get https://nexus.mydomain.com:8082/v2/: http: server gave HTTP response to HTTPS client |
По умолчанию Docker разрешает только SSL-подключение/общение между клиентом и репозитарием Docker. Для разрешения подключению по небезопасному протоколу(HTTP) к Docker-репозитарию, добавляем на Docker-клиенте разрешение на небезопсное подключение к нашему Docker-серверу
1 |
# nano /etc/docker/daemon.json |
1 2 3 |
{ "insecure-registries" : ["nexus.mydomain.com:8082"] } |
Перезапускаем докер и проверяем успешное подключение
1 |
# systemctl restart docker |
1 |
# docker login nexus.mydomain.com:8082 |
1 2 |
Username: my-docker-user Password: |
1 2 3 4 5 |
WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded |
Скачаем образ с официального Docker-сервера и загрузим его на наш приватный Docker-репозитарий
1 |
# docker pull hello-world |
1 |
# docker images |
1 2 |
REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest 2cb0d9787c4d 5 weeks ago 1.85kB |
1 |
# docker tag hello-world nexus.mydomain.com:8082/hello-world:0.1 |
1 |
# docker images |
1 2 3 |
REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest 2cb0d9787c4d 5 weeks ago 1.85kB nexus.mydomain.com:8082/hello-world 0.1 2cb0d9787c4d 5 weeks ago 1.85kB |
1 |
# docker push nexus.mydomain.com:8082/hello-world:0.1 |
1 2 3 |
The push refers to repository [nexus.mydomain.com:8082/hello-world] ee83fc5847cb: Pushed 0.1: digest: sha256:aca41a608e5eb015f1ec6755f490f3be26b48010b178e78c00eac21ffbe246f1 size: 524 |
Проверим наличие образа в репозитарии
1 |
# curl -X GET http://my-docker-user:my-docker-password@nexus.mydomain.com:8082/v2/_catalog |
1 |
{"repositories":["hello-world"]} |
Проверим также доступность образа через HTTPS-подлючение(через Nginx-прокси вирт.хост docker.mydomain.com)
1 |
# curl -X GET https://my-docker-user:my-docker-password@docker.mydomain.com/v2/_catalog |
1 |
{"repositories":["hello-world"]} |
Удалим образ и загрузим его с нашего приватного репозитария
1 |
# docker rmi nexus.mydomain.com:8082/hello-world:0.1 |
1 |
# docker pull nexus.mydomain.com:8082/hello-world:0.1 |
1 2 3 4 |
0.1: Pulling from hello-world 9db2ca6ccae0: Pull complete Digest: sha256:aca41a608e5eb015f1ec6755f490f3be26b48010b178e78c00eac21ffbe246f1 Status: Downloaded newer image for nexus.mydomain.com:8082/hello-world:0.1 |
1 |
# docker images |
1 2 3 |
REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest 2cb0d9787c4d 5 weeks ago 1.85kB nexus.mydomain.com:8082/hello-world 0.1 2cb0d9787c4d 5 weeks ago 1.85kB |
Также загрузим этот же образ,но через HTTPS-соединение(docker.mydomain.com)
1 |
# docker pull docker.mydomain.com/hello-world:0.1 |
1 2 3 4 |
0.1: Pulling from hello-world 9db2ca6ccae0: Pull complete Digest: sha256:aca41a608e5eb015f1ec6755f490f3be26b48010b178e78c00eac21ffbe246f1 Status: Downloaded newer image for docker.mydomain.com/hello-world:0.1 |
1 |
# docker images |
1 2 3 4 |
REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest 2cb0d9787c4d 5 weeks ago 1.85kB docker.mydomain.com/hello-world 0.1 2cb0d9787c4d 5 weeks ago 1.85kB nexus.mydomain.com:8082/hello-world 0.1 2cb0d9787c4d 5 weeks ago 1.85kB |