jenkins docker slave inbound connection with self signed certificate - jenkins

We move our Jenkins to use a self-signed certificate and then docker slaves (inbound, image: jenkins-inbound-agent) strat to fail to connect as the certificate is not trusted.
We try to add -cert #<path to file> and we get an error empty input (we check the file and it is OK)
Second, we tried to add the certificate as env but then it complained about an unknown option -----END CERTIFICATE-----
What can be done?

Related

OpenSSH Server Hostkey RSA without SHA1

Is there away to disable the SHA1 as an option in ssh-keygen for an RSA hostkey?
Trying to use ssh-keygen to create a RSA hostkey without including SHA1
ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key
Per this page: https://man.freebsd.org/cgi/man.cgi?query=ssh-keygen&sektion=1&n=1
This flag may also be used to specify the desired signature type
when signing certificates using an RSA CA key. The available RSA
signature variants are "ssh-rsa" (SHA1 signatures, not recom-
mended), "rsa-sha2-256", and "rsa-sha2-512" (the default).
CentOS Steam 8 with OpenSSH 8 (understood SHA1 is removed in OpenSSH 8.3)
Used the specific -t rsa-sha2-256 and -t rsa-sha2-512 in the ssh-keygen command, but SHA1 is still included.
Updated the sshd_config to point at a key pair generated with the SHA2. removed RSA. restarted sshd. new RSA hostkey is generated on the sshd restart.

Keycloak SSL setup using docker image

I am trying to deploy keycloak using docker image (https://hub.docker.com/r/jboss/keycloak/ version 4.5.0-Final) and facing an issue with setting up SSL.
According to the docs
Keycloak image allows you to specify both a
private key and a certificate for serving HTTPS. In that case you need
to provide two files:
tls.crt - a certificate tls.key - a private key Those files need to be
mounted in /etc/x509/https directory. The image will automatically
convert them into a Java keystore and reconfigure Wildfly to use it.
I followed the given steps and provided the volume mount setting with a folder with the necessary files (tls.crt and tls.key), But I am facing issues with SSL handshake, getting
ERR_SSL_VERSION_OR_CIPHER_MISMATCH
error, blocking keycloak load in browser when trying to access it.
I have used letsencrypt to generate pem files and used openssl to create .crt and .key files.
Also tried just openssl to create those files to narrow down issue and the behavior is same(some additional info if this should matter)
By default, when I simply specify just the port binding -p 8443:8443 without specifying the cert volume mount /etc/x509/https the keycloak server generates a self signed certificate and I don't see issue in viewing the app in browser
I guess this might be more of a certificate creation issue than anything specific to keycloak, But, unsure how to get this to working.
Any help is appreciated
I also faced the issue of getting an ERR_SSL_VERSION_OR_CIPHER_MISMATCH error, using the jboss/keycloak Docker image and free certificates from letsencrypt. Even after considering the advices from the other comments. Now, I have a working (and quite easy) setup, which might also help you.
1) Generate letsencrypt certificate
At first, I generated my letsencrypt certificate for domain sub.example.com using the certbot. You can find detailed instructions and alternative ways to gain a certificate at https://certbot.eff.org/ and the user guide at https://certbot.eff.org/docs/using.html.
$ sudo certbot certonly --standalone
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Please enter in your domain name(s) (comma and/or space separated) (Enter 'c' to cancel): sub.example.com
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for sub.example.com
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/sub.example.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/sub.example.com/privkey.pem
Your cert will expire on 2020-01-27. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
2) Prepare docker-compose environment
I use docker-compose to run keycloak via docker. The config and data files are stored in path /srv/docker/keycloak/.
Folder config contains the docker-compose.yml
Folder data/certs contains the certificates I generated via letsencrypt
Folder data/keycloack_db is mapped to the database container to make its data persistent.
Put the certificate files to the right path
When I first had issues using the original letscrypt certificates for keycloak, I tried the workaround of converting the certificates to another format, as mentioned in the comments of the former answers, which also failed. Eventually, I realized that my problem was caused by permissions set to the mapped certificate files.
So, what worked for me is to just to copy and rename the files provided by letsencrypt, and mount them to the container.
$ cp /etc/letsencrypt/live/sub.example.com/fullchain.pem /srv/docker/keycloak/data/certs/tls.crt
$ cp /etc/letsencrypt/live/sub.example.com/privkey.pem /srv/docker/keycloak/data/certs/tls.key
$ chmod 755 /srv/docker/keycloak/data/certs/
$ chmod 604 /srv/docker/keycloak/data/certs/*
docker-compose.yml
In my case, I needed to use the host network of my docker host. This is not best practice and should not be required for your case. Please find information about configuration parameters in the documentation at hub.docker.com/r/jboss/keycloak/.
version: '3.7'
networks:
default:
external:
name: host
services:
keycloak:
container_name: keycloak_app
image: jboss/keycloak
depends_on:
- mariadb
restart: always
ports:
- "8080:8080"
- "8443:8443"
volumes:
- "/srv/docker/keycloak/data/certs/:/etc/x509/https" # map certificates to container
environment:
KEYCLOAK_USER: <user>
KEYCLOAK_PASSWORD: <pw>
KEYCLOAK_HTTP_PORT: 8080
KEYCLOAK_HTTPS_PORT: 8443
KEYCLOAK_HOSTNAME: sub.example.ocm
DB_VENDOR: mariadb
DB_ADDR: localhost
DB_USER: keycloak
DB_PASSWORD: <pw>
network_mode: host
mariadb:
container_name: keycloak_db
image: mariadb
volumes:
- "/srv/docker/keycloak/data/keycloak_db:/var/lib/mysql"
restart: always
environment:
MYSQL_ROOT_PASSWORD: <pw>
MYSQL_DATABASE: keycloak
MYSQL_USER: keycloak
MYSQL_PASSWORD: <pw>
network_mode: host
Final directory setup
This is how my final file and folder setup looks like.
$ cd /srv/docker/keycloak/
$ tree
.
├── config
│ └── docker-compose.yml
└── data
├── certs
│ ├── tls.crt
│ └── tls.key
└── keycloak_db
Start container
Finally, I was able to start my software using docker-compose.
$ cd /srv/docker/keycloak/config/
$ sudo docker-compose up -d
We can see the mounted certificates within the container.
$ cd /srv/docker/keycloak/config/
$ sudo docker-compose up -d
We can doublecheck the mounted certificates within the container.
## open internal shell of keycloack container
$ sudo docker exec -it keycloak_app /bin/bash
## open directory of certificates
$ cd /etc/x509/https/
$ ll
-rw----r-- 1 root root 3586 Oct 30 14:21 tls.crt
-rw----r-- 1 root root 1708 Oct 30 14:20 tls.key
Considerung the setup from the docker-compose.yml, keycloak is now available at https://sub.example.com:8443
After some research the following method worked (for self-signed certs, I still have to figure out how to do with letsencrypt CA for prod)
generate a self-signed cert using the keytool
keytool -genkey -alias localhost -keyalg RSA -keystore keycloak.jks -validity 10950
convert .jks to .p12
keytool -importkeystore -srckeystore keycloak.jks -destkeystore keycloak.p12 -deststoretype PKCS12
generate .crt from .p12 keystore
openssl pkcs12 -in keycloak.p12 -nokeys -out tls.crt
generate .key from .p12 keystore
openssl pkcs12 -in keycloak.p12 -nocerts -nodes -out tls.key
Then use the tls.crt and tls.key for volume mount /etc/x509/https
Also, on the securing app, in the keycloak.json file specify the following properties
"truststore" : "path/to/keycloak.jks",
"truststore-password" : "<jks-pwd>",
For anyone who is trying to run Keycloak with a passphrase protected private key file:
Keycloak runs the script /opt/jboss/tools/x509.sh to generate the keystore based on the provided files in /etc/x509/https as described in https://hub.docker.com/r/jboss/keycloak - Setting up TLS(SSL).
This script takes no passphrase into account unfortunately. But with a little modification at Docker build time you can fix it by yourself:
Within your Dockerfile add:
RUN sed -i -e 's/-out "${KEYSTORES_STORAGE}\/${PKCS12_KEYSTORE_FILE}" \\/-out "${KEYSTORES_STORAGE}\/${PKCS12_KEYSTORE_FILE}" \\\n -passin pass:"${SERVER_KEYSTORE_PASSWORD}" \\/' /opt/jboss/tools/x509.sh
This command modifies the script and appends the parameter to pass in the passphrase
-passin pass:"${SERVER_KEYSTORE_PASSWORD}"
The value of the parameter is an environment variable which you are free to set: SERVER_KEYSTORE_PASSWORD
Tested with Keycloak 9.0.0

Rust installation fails. The command 'rustup-init -y' throws and error.

I am behind a corporate proxy and I'm trying to install Hyperledger Sawtooth on an Ubuntu machine.
Part of that setup is installing rust which is failing.
It uses the following command which is taken from a 'Dockerfile' file as part of the command docker-compose up:
curl --insecure https://sh.rustup.rs -sSf > /usr/bin/rustup-init && chmod +x /usr/bin/rustup-init && rustup-init -y
This gives me an error:
curl: (60) server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
rustup: command failed: downloader https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init /tmp/tmp.KEMZg5vZRK/rustup-init
Apparently, the command rustup-init -y is failing as I'm behind a corporate proxy and it failed to connect the url https://static.rust-lang.org/rustup/dist/x86_64-unknown-linux-gnu/rustup-init.
Where do I do the modification (add the -k flag) to turn off curl's certificate verification option so that I get an insecure connection and my installation is successful?
I tried modifying the rustup-init.sh file, but it is of no use.

Docker Private Registry - push to 'insecure-registry' still complains about 'unknown authority'

I have a remote Docker registry setup. It has a go-daddy SSL cert installed.
If I curl it I get an 'unknown authority' error:
curl https://example.com:5000/v2/
curl: (60) server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none
More details here: http://curl.haxx.se/docs/sslcerts.html
...
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
So I then use the 'insecure' curl:
curl -k https://example.com:5000/v2
and I get
{} //which I guess is because there is nothing in the registry?
to check, I curl a non-existent endpoint:
curl -k https://example.com:5000/moo
404 page not found //which is positive, as it means the -k flag is suppressing the 'unknown authority' correctly
So, now I know that it is possible to connect to the registry by curl I try using Docker client to push an image:
docker push example.com:5000/my-image
The push refers to a repository [example.com:5000/my-image]
unable to ping registry endpoint https://example.com:5000/v0/
v2 ping attempt failed with error: Get https://example.com:5000/v2/: x509: certificate signed by unknown authority
v1 ping attempt failed with error: Get https://example.com:5000/v1/_ping: x509: certificate signed by unknown authority
So I then try to suppress the error by adding 'insecure-registry' to DOCKER_OPTS (as explained here):
DOCKER_OPTS="--insecure-registry example.com:5000"
[restart docker daemon]
And it does not work. I get the same 'unknown authority' warning.
Firstly, why is a certificate from Go Daddy not trusted? I have it setup on an nginx server and it is working fine with the 'green bar' on the browser.
Secondly, how can I get the 'insecure-registry' to work with Docker? Thanks
Ok, I got to the bottom of this.
Turns out I didn't need to modify /etc/default/docker with this:
DOCKER_OPTS="--insecure-registry example.com:5000"
The issue was that the Go-Daddy certificate I installed in the registry needed to have the intermediate certificates too. I received the following from Go-Daddy:
domain.crt
some-bundle.crt
You need to
cat bundle.crt >> domain.crt
so that the certificate chain is complete. Then it all works fine

Docker private registry using selfsigned certificates

I want to run a private docker registry which is widely available.
So I will be able to push and pull images from other servers.
I'm following this tutorials: doc1 & doc2
I performed 3 steps:
First I've created my certificate and key (as CNAME I filled in my ec2-hostname)
mkdir -p certs && openssl req \
-newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key \
-x509 -days 365 -out certs/domain.crt
Than I've created my docker registry, using this key.
docker run -d -p 5000:5000 --restart=always --name registry \
-v `pwd`/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2
Than I copied the content of domain.crt to /etc/docker/certs.d/ec2-xx-xx-xx-xx.compute.amazonaws.com:5000/ca.crt
I restarted my docker: sudo service docker restart
When I try to push an image I get the following error:
unable to ping registry endpoint https://ec2-xx-xx-xx-xx.compute.amazonaws.com:5000/v0/
v2 ping attempt failed with error: Get https://ec2-xx-xx-xx-xx.compute.amazonaws.com:5000/v2/: net/http: TLS handshake timeout
v1 ping attempt failed with error: Get https://ec2-xx-xx-xx-xx.compute.amazonaws.com:5000/v1/_ping: net/http: TLS handshake timeout
I really don't know what I'm missing or doing wrong. Can someone please help me. Thanks
I'm not sure if you copy/pasted your pwd directly... but the file path should be /etc/docker/certs.d
You currently have etc/docker/cert.d/registry.ip:5000/domain.crt
The error message says "TLS handshake timeout". This indicates that either no process is listening on port 5000 (check using netstat) or the port is closed from the location where you are trying to push the image (open port in the AWS security group).
From what I've seen docker login is way more sensitive to properly crafted self-signed certs than browsers are + there's an interesting gotcha I'll point out at the very bottom, so read the whole thing.
According to this site:
https://jamielinux.com/docs/openssl-certificate-authority/create-the-root-pair.html
Bash# openssl x509 -noout -text -in ca.crt
X509v3 Basic Constraints: critical
CA:TRUE
^You should see something like this is you provisioned your certs right.
While following random how-to guides on the net I was able to generate ca.crt and website.crt
When I ran the above command I didn't see that output, but I noticed:
If I imported the cert as trusted in Mac or Win my browser would be happy and say yeap valid cert, but docker login on RHEL7 would complain with messages like)
x509: certificate signed by unknown authority
I tried following directions related to using: /etc/docker/certs.d/mydockerrepo.lan:5000/ca.crt
on https://docs.docker.com/engine/security/certificates/
It got me a better error message (which caused me to find the above site in the first place)
x509: certificate signed by unknown authority (possibly because of
"x509: invalid signature: parent certificate cannot sign this kind of
certificate" while trying to verify candidate authority certificate
After 2 days of messing around I figured it out:
When I was taught programming I was taught the concept of a short self-contained example, so going to try doing that here for ansible, leveraging the openssl built-in modules, I'm running latest ansible 2.9, but this should work for ansible 2.5++ in theory:
Short Self Contained Example:
#Name this file generatecertificates.playbook.yml
#Run using Bash# ansible-playbook generatecertificates.playbook.yml
#
#What to Expect:
#Run Self Contained Stand Alone Ansible Playbook --Get-->
# currentworkingdir/certs/
# ca.crt
# ca.key
# mydockerrepo.private.crt
# mydockerrepo.private.key
#
#PreReq Ansible 2.5++
#PreReq Bash# pip3 install cryptograph >= 1.6 or PyOpenSSL > 0.15 (if using selfsigned provider)
---
- hosts: localhost
connection: local
gather_facts: no
vars:
- caencryptionpassword: "myrootcaencryptionpassword"
- dockerepodns: "mydockerrepo.private"
- rootcaname: "My Root CA"
tasks:
- name: get current working directory
shell: pwd
register: pathvar
- debug: var=pathvar.stdout
- name: Make sub directory
file:
path: "{{pathvar.stdout}}/certs"
state: directory
register: certsoutputdir
- debug: var=certsoutputdir.path
- name: "Generate Root CA's Encrypted Private Key"
openssl_privatekey:
size: 4096
path: "{{certsoutputdir.path}}/ca.key"
cipher: auto
passphrase: "{{caencryptionpassword}}"
- name: "Generate Root CA's Self Signed Certificate Signing Request"
openssl_csr:
path: "{{certsoutputdir.path}}/ca.csr"
privatekey_path: "{{certsoutputdir.path}}/ca.key"
privatekey_passphrase: "{{caencryptionpassword}}"
common_name: "{{rootcaname}}"
basic_constraints_critical: yes
basic_constraints: ['CA:TRUE']
- name: "Generate Root CA's Self Signed Certificate"
openssl_certificate:
path: "{{certsoutputdir.path}}/ca.crt"
csr_path: "{{certsoutputdir.path}}/ca.csr"
provider: selfsigned
selfsigned_not_after: "+3650d" #Note: Mac won't trust by default due to https://support.apple.com/en-us/HT210176, but you can explitly trust to make it work.
privatekey_path: "{{certsoutputdir.path}}/ca.key"
privatekey_passphrase: "{{caencryptionpassword}}"
register: cert
- debug: var=cert
- name: "Generate Docker Repo's Private Key"
openssl_privatekey:
size: 4096
path: "{{certsoutputdir.path}}/{{dockerepodns}}.key"
- name: "Generate Docker Repo's Certificate Signing Request"
openssl_csr:
path: "{{certsoutputdir.path}}/{{dockerepodns}}.csr"
privatekey_path: "{{certsoutputdir.path}}/{{dockerepodns}}.key"
common_name: "{{dockerepodns}}"
subject_alt_name: 'DNS:{{dockerepodns}},DNS:localhost,IP:127.0.0.1'
- name: "Generate Docker Repo's Cert, signed by Root CA"
openssl_certificate:
path: "{{certsoutputdir.path}}/{{dockerepodns}}.crt"
csr_path: "{{certsoutputdir.path}}/{{dockerepodns}}.csr"
provider: ownca
ownca_not_after: "+365d" #Cert valid 1 year
ownca_path: "{{certsoutputdir.path}}/ca.crt"
ownca_privatekey_path: "{{certsoutputdir.path}}/ca.key"
ownca_privatekey_passphrase: "{{caencryptionpassword}}"
register: cert
- debug: var=cert
Interesting Gotcha/Final Step:
RHEL7Bash# sudo cp ca.crt /etc/pki/ca-trust/source/anchors/ca.crt
RHEL7Bash# sudo update-ca-trust
RHEL7Bash# sudo systemctl restart docker
The gotcha is that you have to restart docker, for docker login to recognize updates to CA's newly added to the system.

Resources