起因

第一个问题是我们为什么要用私有仓库?

私有仓库的好处有很多,比如我们可以自己控制版本,可以自己控制发布的内容,可以自己控制发布内容的权限等等。

第二个问题是当前搭建私有的 nexus 仓库有哪些坑?

自从 maven 3.8.1 开始,默认不允许使用 http 协议拉取依赖,只允许 https 协议(否则就要修改一系列的配置),所以需要配置 nexus 使用 https 协议。 但配置 https 对于对于内网私有仓库就有了问题,因为内网没有公网域名或者而ip,因此没办法找到一个域名颁发机构,为私有 ip 颁发 https 证书,这个时候就需要自己生成对应的自签证书来解决 https 证书的问题。

第三个问题是除了本文中的搭建 nexus 并自签证书之外是否可以有一个好的解决方案?

有的

最简单方案:

公网搭建服务,内网使用域名来访问,这样就不需要自签证书,使用公网证书,域名访问,https 协议,完美解决。

稍微复杂一点的方案:

内网搭建服务,内网使用域名来访问,内网 DNS 统一管理,这样就不需要自签证书,使用公网证书,域名访问,https 协议访问,完美解决。

本文的最复杂方案:

内网搭建服务,内网使用 ip 来访问,自签证书,https 协议访问,这里就有两个问题,

  1. 自签证书,浏览器不信任,需要手动添加信任。
  2. 自签证书,maven 不信任,需要手动添加信任,这里采用 keytool。

如何搭建私有仓库

部署 nexus

部署软件最简单的方案就是采用 docker 容器化部署,这里我使用 sonatype/nexus3 镜像来搭建私有仓库。

为了方便,且可以持久化数据,我使用 docker-compose 来搭建。

创建 nexus 的文件夹

mkdir nexus

并进入到 nexus 文件夹 创建 docker-compose.yml 文件

cd nexus
touch docker-compose.yml

具体 docker-compose.yml 文件内容如下

version: "3.3"
services:
  nexus:
    image: sonatype/nexus3
    container_name: nexus3
    restart: always
    environment:
      - TZ=Asia/Shanghai
    ports:
      - 8081:8081
    volumes:
      - ./data:/nexus-data

这里我使用了 8081 端口,如果你的服务器上有其他服务使用了 8081 端口,可以修改为其他端口(比如想用宿主机的8090 端口可以修改上述的 ports 为 8090:8081)。

然后执行 docker-compose up -d 即可启动 nexus 服务。

访问 http://your-ip:8081 即可看到 nexus 的登录页面。

点击登录可以看到需要输入账号密码信息。

如何搭建私有仓库 Nexus 并配置 SSL 证书_私有仓库

如何查看默认密码

docker exec -it nexus3 cat /nexus-data/admin.password

然后在页面中就登录到 nexus 了,首先展示的是修改密码页面。

然后就可以修改对应的密码了。

这里有一个文件权限的问题,可能第一次启动不成功,最简单的话 可以如下修改权限即可

chown -R 200:200 ./data

使用 nginx 代理 ssl

搭建 nginx 并增加如下配置

server {
    listen 8443 ssl; # 监听443端口,并使用SSL

    ssl_certificate /Users/xxx/Desktop/cert/10.10.9.10.pem; # SSL证书路径
    ssl_certificate_key /Users/xxx/Desktop/cert/10.10.9.10-key.pem; # SSL私钥路径

    location / {
        proxy_pass http://localhost:8081; # 转发到内网8081端口
        proxy_set_header Host $host;
	      proxy_set_header X-Forwarded-Proto "https";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	 			proxy_set_header Content-Length $content_length;
    }
}

自签 ssl 证书并添加信任

这部分并不是必须的,如果你的 nexus 仓库是公网的,或者可以申请域名证书,那么可以直接使用公网证书,如果是内网的,那么方案就只能是自签证书了。

自签证书相对来说麻烦一些,你需要手动创建证书,并且将证书添加到可信证书管理中。

比如我们这里就需要自己创建证书,因为浏览器不信任自签证书,因此手动添加信任,因为 java 不信任自签证书,需要使用 keytool 手动添加信任。

自签证书

这里为了简单 我们使用 mkcert 来生成证书, 如果使用 openssl 生成自签证书,可参照 https://docs.pingcap.com/zh/tidb/stable/generate-self-signed-certificates 内容

下面的内容是 Mac 的安装教程,如果使用其他内容,可以参照 https://github.com/FiloSottile/mkcert 这个代码仓库的Readme

# 安装 mkcert
brew install mkcert

mkdir ./mkcert-cer

# 使用 mkcert 安装根证书 此时已经自动添加到本地的信任库中,在 mac 上是 keychain Access -> System -> Certificates
mkcert install 

# 使用 mkcert 签名指定域名
mkcert 10.10.9.10

添加信任

添加信任其实主要添加的是 CA(Certificate Authority) 证书的信任,即根证书的信任,信任了根证书,其他由根证书签发的证书也就自动信任了,

能否只信任签发证书呢? 可以的,但是增加了我们的复杂性,比如需要手动信任下级证书,使用自定义信任链等内容,这增加了我们对于自签证书的工作量。

添加浏览器信任

如果通过 mkcert 生成的证书,其实在 mkcert install 的时候已经信任过了,在mac 的证书服务中,可以看到对应的证书已经存在。

如何搭建私有仓库 Nexus 并配置 SSL 证书_内网_02

双击可以对其添加信任

如何搭建私有仓库 Nexus 并配置 SSL 证书_maven_03

添加 java 信任

命令如下:

keytool -import -alias nexus-self-sign -keystore  "/Users/lihui/.sdkman/candidates/java/17.0.11-amzn/lib/security/cacerts" -file mkcert_lihui@bogon.cer

如何知道自己当前使用的哪一个目录 java 呢?

where java

既可找到对应的 java 的目录信息,如果是 sdkman 可能 java 的位置有些差异,

与 Springboot 集成

前提条件

  1. 已经搭建好 nexus 仓库
  2. 已经为 nexus 仓库配置好 ssl 证书
  3. 本地已经配置好浏览器的 https 证书 以及 java 的 https 证书认证
配置 maven

在 Springboot 集成的时候主要有两个问题,即需要使用 https 的要求,以及如果使用自签的 https 证书 java 不信任的问题。

发布到私有仓库

代码仓库配置远端地址

在 maven 的 pom.xml 中的 project 层级(即项目层级)下增加如下信息

<distributionManagement>
        <repository>
            <id>private-releases</id>
            <name>私有 release 仓库</name>
            <url>https://10.10.9.10:8443/repository/maven-releases/</url>
        </repository>
        <snapshotRepository>
            <id>private-snapshot</id>
            <name>私有 snapshot 仓库</name>
            <url>http://10.10.9.10:8443/repository/maven-snapshots/</url>
        </snapshotRepository>
    </distributionManagement>
发布到远程仓库

直接使用 maven 的 deploy 地址即可将其提交到远端地址。

打开远端地址可以看到如下内容

如何搭建私有仓库 Nexus 并配置 SSL 证书_私有仓库_04

从私有仓库拉取

配置私有仓库信息

在 maven 的 pom.xml 中的 project 层级(即项目层级)下增加如下信息

<repositories>
          <repository>
            <id>private-releases</id>
            <name>私有 release 仓库</name>
            <url>https://10.10.9.10:8443/repository/maven-releases/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>

此时即可使用 maven 的 clean package 进行下载私有仓库的依赖信息。当前也首先要在 dependencies 中增加自己的私有仓库的包。

附录

如何将证书分享给其他人
1. 导出证书

右键点击导出,即可导出对应的 CA 公钥证书,将证书文件发送给其他人即可。

如何搭建私有仓库 Nexus 并配置 SSL 证书_私有仓库_05

2. 安装证书

双击证书文件即可安装,再如上添加信任即可通过浏览器访问自签的网站地址。