harbor/docs/configure_https.md
2019-10-22 10:29:25 +02:00

195 lines
6.6 KiB
Markdown

# Configuring Harbor with HTTPS Access
Because Harbor does not ship with any certificates, it uses HTTP by default to serve registry requests. However, using HTTP is acceptable only in air-gapped test or development environments that do not have a connection to the external internet. Using HTTP in environments that are not air-gapped exposes you to man-in-the-middle attacks. In production environments, always use HTTPS. If you enable Content Trust with Notary to properly sign all images, you must use HTTPS.
Harbor uses an `nginx` instance as a reverse proxy for all services. You use the `prepare` script to configure `nginx` to enable HTTPS.
You can use certificates that are signed by a trusted third-party CA, or you can use self-signed certificates. The following sections describe how to create a CA, and how to use your CA to sign a server certificate and a client certificate.
## Getting Certificate Authority
```
openssl genrsa -out ca.key 4096
```
```
openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=TW/ST=Taipei/L=Taipei/O=example/OU=Personal/CN=yourdomain.com" \
-key ca.key \
-out ca.crt
```
## Getting Server Certificate
Assuming that your registry's **hostname** is **yourdomain.com**, and that its DNS record points to the host where you are running Harbor. In production environment, you first should get a certificate from a CA. In a test or development environment, you can use your own CA. The certificate usually contains a .crt file and a .key file, for example, **yourdomain.com.crt** and **yourdomain.com.key**.
**1) Create your own Private Key:**
```
openssl genrsa -out yourdomain.com.key 4096
```
**2) Generate a Certificate Signing Request:**
If you use FQDN like **yourdomain.com** to connect your registry host, then you must use **yourdomain.com** as CN (Common Name).
```
openssl req -sha512 -new \
-subj "/C=TW/ST=Taipei/L=Taipei/O=example/OU=Personal/CN=yourdomain.com" \
-key yourdomain.com.key \
-out yourdomain.com.csr
```
**3) Generate the certificate of your registry host:**
Whether you're using FQDN like **yourdomain.com** or IP to connect your registry host, run this command to generate the certificate of your registry host which comply with Subject Alternative Name (SAN) and x509 v3 extension requirement:
**v3.ext**
```
cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1=yourdomain.com
DNS.2=yourdomain
DNS.3=hostname
EOF
```
```
openssl x509 -req -sha512 -days 3650 \
-extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in yourdomain.com.csr \
-out yourdomain.com.crt
```
## Configuration and Installation
**1) Configure Server Certificate and Key for Harbor**
After obtaining the **yourdomain.com.crt** and **yourdomain.com.key** files,
you can put them into directory such as ```/root/cert/```:
```
cp yourdomain.com.crt /data/cert/
cp yourdomain.com.key /data/cert/
```
**2) Configure Server Certificate, Key and CA for Docker**
The Docker daemon interprets ```.crt``` files as CA certificates and ```.cert``` files as client certificates.
Convert server ```yourdomain.com.crt``` to ```yourdomain.com.cert```:
```
openssl x509 -inform PEM -in yourdomain.com.crt -out yourdomain.com.cert
```
Delpoy ```yourdomain.com.cert```, ```yourdomain.com.key```, and ```ca.crt``` for Docker:
```
cp yourdomain.com.cert /etc/docker/certs.d/yourdomain.com/
cp yourdomain.com.key /etc/docker/certs.d/yourdomain.com/
cp ca.crt /etc/docker/certs.d/yourdomain.com/
```
The following illustrates a configuration with custom certificates:
```
/etc/docker/certs.d/
└── yourdomain.com:port
├── yourdomain.com.cert <-- Server certificate signed by CA
├── yourdomain.com.key <-- Server key signed by CA
└── ca.crt <-- Certificate authority that signed the registry certificate
```
Notice that you may need to trust the certificate at OS level. Please refer to the [Troubleshooting](#Troubleshooting) section below.
**3) Configure Harbor**
Edit the file `harbor.yml`, update the hostname and uncomment the https block, and update the attributes `certificate` and `private_key`:
```yaml
#set hostname
hostname: yourdomain.com
http:
port: 80
https:
# https port for harbor, default is 443
port: 443
# The path of cert and key files for nginx
certificate: /data/cert/yourdomain.com.crt
private_key: /data/cert/yourdomain.com.key
......
```
Generate configuration files for Harbor:
```
./prepare
```
If Harbor is already running, stop and remove the existing instance. Your image data remain in the file system
```
docker-compose down -v
```
Finally, restart Harbor:
```
docker-compose up -d
```
After setting up HTTPS for Harbor, you can verify it by the following steps:
* Open a browser and enter the address: https://yourdomain.com. It should display the user interface of Harbor.
* Notice that some browser may still shows the warning regarding Certificate Authority (CA) unknown for security reason even though we signed certificates by self-signed CA and deploy the CA to the place mentioned above. It is because self-signed CA essentially is not a trusted third-party CA. You can import the CA to the browser on your own to solve the warning.
* On a machine with Docker daemon, make sure the option "-insecure-registry" for https://yourdomain.com is not present.
* If you mapped nginx port 443 to another port, then you should instead create the directory ```/etc/docker/certs.d/yourdomain.com:port``` (or your registry host IP:port). Then run any docker command to verify the setup, e.g.
```
docker login yourdomain.com
```
If you've mapped nginx 443 port to another, you need to add the port to login, like below:
```
docker login yourdomain.com:port
```
## Troubleshooting
1. You may get an intermediate certificate from a certificate issuer. In this case, you should merge the intermediate certificate with your own certificate to create a certificate bundle. You can achieve this by the below command:
```
cat intermediate-certificate.pem >> yourdomain.com.crt
```
2. On some systems where docker daemon runs, you may need to trust the certificate at OS level.
On Ubuntu, this can be done by below commands:
```sh
cp yourdomain.com.crt /usr/local/share/ca-certificates/yourdomain.com.crt
update-ca-certificates
```
On Red Hat (CentOS etc), the commands are:
```sh
cp yourdomain.com.crt /etc/pki/ca-trust/source/anchors/yourdomain.com.crt
update-ca-trust
```