16 Commits
v1.0 ... v2.1

Author SHA1 Message Date
c5dead142f Merge pull request 'Remove certificates from IPA tracking on repo rebuild' (#39) from dev into master
Reviewed-on: https://remvpn.olssonul.com/IaC/rproxy/pulls/39
2025-08-16 15:30:31 +03:00
11cf16ff53 Remove certificates from IPA tracking on repo rebuild 2025-08-16 15:28:48 +03:00
81af5f3922 Merge pull request 'Move to FreeIPA CA certificate generation' (#38) from dev into master
Reviewed-on: https://remvpn.olssonul.com/IaC/rproxy/pulls/38
2025-08-15 00:16:54 +03:00
de3484c826 Ignore if rproxy already allow to fetch certificates 2025-08-15 00:15:32 +03:00
a738ee71a8 Fix certs name for service 2025-08-15 00:13:45 +03:00
d9ec475184 Ignore if fake host already exists 2025-08-15 00:11:47 +03:00
d7919a4a45 Allow rproxy generate certificates for proxy host 2025-08-15 00:09:06 +03:00
f4717d9d69 Add fake host creation for certificate create 2025-08-15 00:03:23 +03:00
eae462797c Fix SPN name request 2025-08-14 23:54:13 +03:00
18a1e94100 Qa FreeIPA CA certificate generation 2025-08-14 23:50:01 +03:00
191fe274bf Merge pull request 'Allow users PUT, DELETE or MKCOL in public repo' (#36) from dev into master
Reviewed-on: https://remvpn.olssonul.com/IaC/rproxy/pulls/36
2025-08-05 23:52:44 +03:00
ce83125591 Merge pull request 'Allow users PUT, DELETE or MKCOL in public repo' (#35) from feature/webdav_module into dev
Reviewed-on: https://remvpn.olssonul.com/IaC/rproxy/pulls/35
2025-08-05 23:52:18 +03:00
0aa2ab5c69 Allow users PUT, DELETE or MKCOL in public repo 2025-08-05 23:52:00 +03:00
821cc7502c Fix rebuild errors on RootCA files permissions 2025-08-02 17:21:58 +03:00
0edadd8325 Merge pull request 'Auto pull root certificate and key from Jenkins vault' (#33) from dev into master
Reviewed-on: https://remvpn.olssonul.com/IaC/rproxy/pulls/33
2025-07-29 01:27:49 +03:00
e699b31105 Auto pull root certificate and key from Jenkins vault 2025-07-29 01:26:59 +03:00
9 changed files with 166 additions and 243 deletions

14
Jenkinsfile vendored
View File

@@ -33,20 +33,6 @@ pipeline {
}
}
}
stage('Save certs') {
when {
expression {
return params.rproxy_install
}
}
steps {
script {
def userInput = input message: 'Upload RootCA certificate and key', parameters: [base64File(name: 'rootca'), base64File(name: 'rootca_key')]
writeFile(file: 'roles/rproxy/files/RootCA.crt', text: new String(userInput['rootca'].decodeBase64()))
writeFile(file: 'roles/rproxy/files/RootCA.key', text: new String(userInput['rootca_key'].decodeBase64()))
}
}
}
stage('Prepare inventory') {
steps {
script {

View File

@@ -37,17 +37,7 @@ Files should be stored in /opt/rproxy/repo/ to be shared.
## Docker-registry
Would be installed with rproxy service. Hosted on port 5000.
Images would be stored in /opt/dockerrepo/repo/. Uses SSL so you should have trust with root certificate. \
Install trust with root certificate:
```bash
# RHEL based
openssl x509 -in RootCA.crt -out RootCA.pem -outform PEM
mv RootCA.pem /etc/pki/ca-trust/source/anchors/
update-ca-trust force-enable
# Debian based
mv RootCA.crt /usr/local/share/ca-certificates/
update-ca-certificates
```
Install trust with root certificate
How to store image:
```bash
# After image build

View File

@@ -16,6 +16,12 @@ server {
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
dav_methods PUT DELETE MKCOL;
dav_access user:rw group:r all:r;
create_full_put_path on;
client_max_body_size 100m;
# auth_basic "Needs to auth";
# auth_basic_user_file /etc/nginx/.htpasswd;
}

View File

@@ -8,90 +8,7 @@
- name: Generate certificates for {{ rproxy_service_name }}
block:
- name: "Generate {{ rproxy_service_name }}.key"
community.crypto.openssl_privatekey:
path: "{{ rproxy_dir }}/certs/{{ rproxy_service_name }}.key"
size: "2048"
- name: "Generate {{ rproxy_service_name }}.csr"
community.crypto.openssl_csr:
path: "{{ rproxy_dir }}/certs/{{ rproxy_service_name }}.csr"
privatekey_path: "{{ rproxy_dir }}/certs/{{ rproxy_service_name }}.key"
country_name: "RU"
state_or_province_name: "RU"
locality_name: "MSK"
organization_name: "{{ ansible_domain }}"
organizational_unit_name: "IT"
common_name: "{{ rproxy_service_name }}.{{ ansible_facts['domain'] }}"
email_address: "admin@{{ ansible_domain }}"
subject_alt_name: "DNS:{{ rproxy_service_name }}.{{ ansible_facts['domain'] }},DNS:{{ ansible_facts['hostname'] }}.{{ ansible_facts['domain'] }},IP:{{ ansible_facts['default_ipv4']['address'] }}"
key_usage:
- digitalSignature
- nonRepudiation
- keyEncipherment
- dataEncipherment
extended_key_usage:
- serverAuth
- name: "Generate {{ rproxy_service_name }}.crt"
community.crypto.x509_certificate:
csr_path: "{{ rproxy_dir }}/certs/{{ rproxy_service_name }}.csr"
path: "{{ rproxy_dir }}/certs/{{ rproxy_service_name }}.crt"
privatekey_path: "{{ rproxy_dir }}/certs/{{ rproxy_service_name }}.key"
provider: ownca
ownca_create_subject_key_identifier: always_create
ownca_path: "{{ rproxy_dir }}/certs/RootCA.crt"
ownca_privatekey_path: "{{ rproxy_dir }}/certs/RootCA.key"
ownca_not_after: "+365d"
- name: Create fullchain certificate
ansible.builtin.shell:
cmd: 'cat {{ rproxy_dir }}/certs/RootCA.crt >> {{ rproxy_dir }}/certs/{{ rproxy_service_name }}.crt'
- name: Delete csr
ansible.builtin.file:
path: "{{ rproxy_dir }}/certs/{{ rproxy_service_name }}.csr"
state: absent
- name: Restart rproxy
block:
- name: Restart container
containers.podman.podman_container:
name: rproxy
image: "docker.io/library/nginx:{{ rproxy_version }}"
state: started
restart: true
ports:
- "443:443"
- "80:80"
- "9000:9000"
volumes:
- '{{ rproxy_dir }}/nginx.conf:/etc/nginx/nginx.conf:z,rw'
- '{{ rproxy_dir }}/sites:/etc/nginx/sites:z,rw'
- '{{ rproxy_dir }}/certs:/etc/nginx/certs:z,rw'
- '{{ repo_data_dir }}:/repo:z,rw'
- "/etc/localtime:/etc/localtime:ro"
privileged: true
security_opt:
- "label=disable"
log_driver: journald
generate_systemd:
path: /etc/systemd/system/
restart_policy: always
stop_timeout: 120
names: true
- name: Daemon reload
ansible.builtin.shell:
cmd: systemctl daemon-reload
- name: Enable rproxy service
ansible.builtin.systemd:
name: "container-rproxy.service"
state: started
enabled: yes
- name: Create CNAME dns record
- name: Create CNAME dns record
community.general.ipa_dnsrecord:
ipa_user: "{{ ansible_user }}"
ipa_pass: "{{ ansible_password }}"
@@ -100,3 +17,66 @@
record_type: 'CNAME'
record_value: "{{ ansible_facts['hostname'] }}"
state: present
- name: Kinit
ansible.builtin.shell:
cmd: "echo '{{ ansible_password }}' | kinit"
become: false
become_user: "{{ ansible_user }}"
- name: Create fake host for certificate
ansible.builtin.shell:
cmd: "ipa host-add {{ rproxy_service_name }}.{{ ansible_facts['domain'] }} --force --desc=\"Fake host for SPN\""
become: false
become_user: "{{ ansible_user }}"
ignore_errors: true
- name: Create SPN for HTTP
ansible.builtin.shell:
cmd: "ipa service-add HTTP/{{ rproxy_service_name }}.{{ ansible_facts['domain'] }} --skip-host-check --force"
become: false
become_user: "{{ ansible_user }}"
ignore_errors: true
- name: "Allow {{ ansible_facts['hostname'] }}.{{ ansible_facts['domain'] }} to get certificates for HTTP/{{ rproxy_service_name }}.{{ ansible_facts['domain'] }} SPN "
ansible.builtin.shell:
cmd: "ipa service-add-host --hosts={{ ansible_facts['hostname'] }}.{{ ansible_facts['domain'] }} HTTP/{{ rproxy_service_name }}.{{ ansible_facts['domain'] }}"
become: false
become_user: "{{ ansible_user }}"
ignore_errors: true
- name: Request certificate via ipa-getcert
ansible.builtin.command: >
ipa-getcert request
-f {{ rproxy_dir }}/certs/{{ rproxy_service_name }}.{{ ansible_facts['domain'] }}.crt
-k {{ rproxy_dir }}/certs/{{ rproxy_service_name }}.{{ ansible_facts['domain'] }}.key
-K HTTP/{{ rproxy_service_name }}.{{ ansible_facts['domain'] }}
-N CN={{ rproxy_service_name }}.{{ ansible_facts['domain'] }}
# sudo ipa-getcert stop-tracking -i 20250813210258 if track already exists
- name: Wait for certificate to appear
ansible.builtin.wait_for:
path: "{{ rproxy_dir }}/certs/{{ rproxy_service_name }}.{{ ansible_facts['domain'] }}.crt"
timeout: 60
- name: Change certificate permissions
ansible.builtin.file:
path: "{{ rproxy_dir }}/certs/{{ rproxy_service_name }}.{{ ansible_facts['domain'] }}.crt"
mode: "0744"
- name: Wait for certificate key to appear
ansible.builtin.wait_for:
path: "{{ rproxy_dir }}/certs/{{ rproxy_service_name }}.{{ ansible_facts['domain'] }}.key"
timeout: 60
- name: Change certificate key permissions
ansible.builtin.file:
path: "{{ rproxy_dir }}/certs/{{ rproxy_service_name }}.{{ ansible_facts['domain'] }}.key"
mode: "0744"
- name: Restart rproxy service
ansible.builtin.systemd:
name: "container-rproxy.service"
state: restarted
enabled: yes

View File

@@ -23,50 +23,48 @@
- name: Create certificates for image repository
block:
- name: "Generate dockerrepo.key"
community.crypto.openssl_privatekey:
path: "{{ dockerrepo_dir }}/certs/dockerrepo.key"
size: "2048"
- name: "Generate server.csr"
community.crypto.openssl_csr:
path: "{{ dockerrepo_dir }}/certs/dockerrepo.csr"
privatekey_path: "{{ dockerrepo_dir }}/certs/dockerrepo.key"
country_name: "RU"
state_or_province_name: "RU"
locality_name: "MSK"
organization_name: "{{ ansible_domain }}"
organizational_unit_name: "IT"
common_name: "{{ ansible_facts['hostname'] }}.{{ ansible_facts['domain'] }}"
email_address: "admin@{{ ansible_domain }}"
subject_alt_name: "DNS:{{ ansible_facts['hostname'] }}.{{ ansible_facts['domain'] }},DNS:imagerepo.{{ ansible_facts['domain'] }},IP:{{ ansible_facts['default_ipv4']['address'] }}"
key_usage:
- digitalSignature
- nonRepudiation
- keyEncipherment
- dataEncipherment
extended_key_usage:
- serverAuth
- name: "Generate server.crt"
community.crypto.x509_certificate:
csr_path: "{{ dockerrepo_dir }}/certs/dockerrepo.csr"
path: "{{ dockerrepo_dir }}/certs/dockerrepo.crt"
privatekey_path: "{{ dockerrepo_dir }}/certs/dockerrepo.key"
provider: ownca
ownca_create_subject_key_identifier: always_create
ownca_path: "{{ rproxy_dir }}/certs/RootCA.crt"
ownca_privatekey_path: "{{ rproxy_dir }}/certs/RootCA.key"
ownca_not_after: "+365d"
- name: Create fullchain certificate
- name: Kinit
ansible.builtin.shell:
cmd: 'cat {{ rproxy_dir }}/certs/RootCA.crt >> {{ dockerrepo_dir }}/certs/dockerrepo.crt'
cmd: "echo '{{ ansible_password }}' | kinit"
become: false
become_user: "{{ ansible_user }}"
- name: Delete csr
- name: Create SPN for HTTP
ansible.builtin.shell:
cmd: "ipa service-add HTTP/{{ ansible_facts['hostname'] }}.{{ ansible_facts['domain'] }}"
become: false
become_user: "{{ ansible_user }}"
ignore_errors: true
- name: Request certificate via ipa-getcert
ansible.builtin.command: >
ipa-getcert request
-f {{ rproxy_dir }}/certs/dockerrepo.crt
-k {{ rproxy_dir }}/certs/dockerrepo.key
-K HTTP/{{ ansible_facts['hostname'] }}.{{ ansible_facts['domain'] }}
-N CN={{ ansible_facts['hostname'] }}.{{ ansible_facts['domain'] }}
# sudo ipa-getcert stop-tracking -i 20250813210258 if track already exists
- name: Wait for certificate to appear
ansible.builtin.wait_for:
path: "{{ rproxy_dir }}/certs/dockerrepo.crt"
timeout: 60
- name: Change certificate permissions
ansible.builtin.file:
path: "{{ dockerrepo_dir }}/certs/dockerrepo.csr"
state: absent
path: "{{ rproxy_dir }}/certs/dockerrepo.crt"
mode: "0744"
- name: Wait for certificate key to appear
ansible.builtin.wait_for:
path: "{{ rproxy_dir }}/certs/dockerrepo.key"
timeout: 60
- name: Change certificate key permissions
ansible.builtin.file:
path: "{{ rproxy_dir }}/certs/dockerrepo.key"
mode: "0744"
- name: Start image repository
block:

View File

@@ -14,85 +14,61 @@
- name: Create https certificates for repository
block:
- name: "Generate repo.key"
community.crypto.openssl_privatekey:
path: "{{ rproxy_dir }}/certs/repo.key"
size: "2048"
- name: Kinit
ansible.builtin.shell:
cmd: "echo '{{ ansible_password }}' | kinit"
become: false
become_user: "{{ ansible_user }}"
- name: "Generate server.csr"
community.crypto.openssl_csr:
path: "{{ rproxy_dir }}/certs/repo.csr"
privatekey_path: "{{ rproxy_dir }}/certs/repo.key"
country_name: "RU"
state_or_province_name: "RU"
locality_name: "MSK"
organization_name: "{{ ansible_domain }}"
organizational_unit_name: "IT"
common_name: "{{ ansible_facts['hostname'] }}.{{ ansible_facts['domain'] }}"
email_address: "admin@{{ ansible_domain }}"
subject_alt_name: "DNS:{{ ansible_facts['hostname'] }}.{{ ansible_facts['domain'] }},DNS:repo.{{ ansible_facts['domain'] }},IP:{{ ansible_facts['default_ipv4']['address'] }}"
key_usage:
- digitalSignature
- nonRepudiation
- keyEncipherment
- dataEncipherment
extended_key_usage:
- serverAuth
- name: Create SPN for HTTP
ansible.builtin.shell:
cmd: "ipa service-add HTTP/{{ ansible_facts['hostname'] }}.{{ ansible_facts['domain'] }}"
become: false
become_user: "{{ ansible_user }}"
ignore_errors: true
- name: "Generate server.crt"
community.crypto.x509_certificate:
csr_path: "{{ rproxy_dir }}/certs/repo.csr"
- name: Request certificate via ipa-getcert
ansible.builtin.command: >
ipa-getcert request
-f {{ rproxy_dir }}/certs/repo.crt
-k {{ rproxy_dir }}/certs/repo.key
-K HTTP/{{ ansible_facts['hostname'] }}.{{ ansible_facts['domain'] }}
-N CN={{ ansible_facts['hostname'] }}.{{ ansible_facts['domain'] }}
-F {{ rproxy_dir }}/certs/RootCA.crt
- name: Get all tracking certificates
ansible.builtin.shell:
cmd: ipa-getcert list | grep "ID" | awk '{print $NF}' | tr -d "'\|:"
register: tracking_list
- name: Remove certificates from IPA tracking
ansible.builtin.shell:
cmd: "ipa-getcert stop-tracking -i {{ item }}"
loop: "{{ tracking_list.stdout_lines }}"
ignore_errors: true
- name: Wait for certificate to appear
ansible.builtin.wait_for:
path: "{{ rproxy_dir }}/certs/repo.crt"
privatekey_path: "{{ rproxy_dir }}/certs/repo.key"
provider: ownca
ownca_create_subject_key_identifier: always_create
ownca_path: "{{ rproxy_dir }}/certs/RootCA.crt"
ownca_privatekey_path: "{{ rproxy_dir }}/certs/RootCA.key"
ownca_not_after: "+365d"
timeout: 60
- name: Create fullchain certificate
ansible.builtin.shell:
cmd: 'cat {{ rproxy_dir }}/certs/RootCA.crt >> {{ rproxy_dir }}/certs/repo.crt'
- name: Delete csr
- name: Change certificate permissions
ansible.builtin.file:
path: "{{ rproxy_dir }}/certs/repo.csr"
state: absent
path: "{{ rproxy_dir }}/certs/repo.crt"
mode: "0744"
- name: Restart rproxy
block:
- name: Restart container
containers.podman.podman_container:
name: rproxy
image: "docker.io/library/nginx:{{ rproxy_version }}"
state: started
restart: true
ports:
- "443:443"
- "80:80"
- "9000:9000"
volumes:
- '{{ rproxy_dir }}/nginx.conf:/etc/nginx/nginx.conf:z,rw'
- '{{ rproxy_dir }}/sites:/etc/nginx/sites:z,rw'
- '{{ rproxy_dir }}/certs:/etc/nginx/certs:z,rw'
- '{{ repo_data_dir }}:/repo:z,rw'
- "/etc/localtime:/etc/localtime:ro"
privileged: true
security_opt:
- "label=disable"
log_driver: journald
generate_systemd:
path: /etc/systemd/system/
restart_policy: always
stop_timeout: 120
names: true
- name: Wait for certificate key to appear
ansible.builtin.wait_for:
path: "{{ rproxy_dir }}/certs/repo.key"
timeout: 60
- name: Daemon reload
ansible.builtin.shell:
cmd: systemctl daemon-reload
- name: Change certificate key permissions
ansible.builtin.file:
path: "{{ rproxy_dir }}/certs/repo.key"
mode: "0744"
- name: Enable rproxy service
- name: Restart rproxy service
ansible.builtin.systemd:
name: "container-rproxy.service"
state: started
state: restarted
enabled: yes

View File

@@ -36,16 +36,6 @@
src: files/nginx.conf
dest: "{{ rproxy_dir }}/nginx.conf"
- name: Copy RootCA certificate
ansible.builtin.copy:
src: files/RootCA.crt
dest: '{{ rproxy_dir }}/certs/RootCA.crt'
- name: Copy RootCA key
ansible.builtin.copy:
src: files/RootCA.key
dest: '{{ rproxy_dir }}/certs/RootCA.key'
- name: Install rproxy
block:
- name: Pull rproxy image
@@ -83,12 +73,9 @@
stop_timeout: 120
names: true
- name: Daemon reload
ansible.builtin.shell:
cmd: systemctl daemon-reload
- name: Enable rproxy service
ansible.builtin.systemd:
name: "container-rproxy.service"
state: started
enabled: yes
daemon_reload: yes

View File

@@ -15,8 +15,8 @@ server {
server_name {{ rproxy_service_name }}.{{ ansible_domain }};
access_log /var/log/nginx/{{ rproxy_service_name }}.access.log;
error_log /var/log/nginx/{{ rproxy_service_name }}.error.log;
ssl_certificate /etc/nginx/certs/{{ rproxy_service_name }}.crt;
ssl_certificate_key /etc/nginx/certs/{{ rproxy_service_name }}.key;
ssl_certificate /etc/nginx/certs/{{ rproxy_service_name }}.{{ ansible_domain }}.crt;
ssl_certificate_key /etc/nginx/certs/{{ rproxy_service_name }}.{{ ansible_domain }}.key;
ssl_protocols TLSv1.2;
ssl_ciphers EECDH:+AES256:-3DES:!RSA+AES:!RSA+3DES:!NULL:!RC4;
ssl_prefer_server_ciphers on;

View File

@@ -1,6 +1,6 @@
ansible_python_interpreter: /usr/bin/python3
rproxy_dir: /opt/rproxy
rproxy_version: latest
rproxy_version: 1.29.0
data_dir: /opt/data
repo_data_dir: /opt/data/repo
dockerrepo_dir: /opt/dockerrepo