Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nginx reverse proxy configuration #9

Merged
merged 4 commits into from
Mar 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,21 @@ This role supports the following,
- `opencast_opensearch_started`
- By default, the OpenSearch service will (re)start if something has changed that requires the service to be restarted. This is done via the Ansible notification handler. However, if you expect the OpenSearch service to be running when you run this role, you can force the service to start by setting the value to `true`.
- Defaults to `false` (make use of Ansible Handler to reach the state)
- `opencast_opensearch_remote_user`
- `opencast_opensearch_remote_password`
- Since Opencast 16 OpenSearch should be reachable by Admin and Presentation Opencast node.
To secure the connection from Opencast to OpenSearch an reverse proxy should be used.
The Ansible role [elan.opencast_nginx](https://github.com/elan-ev/opencast_nginx) is recommended for this purpose.
Defining `opencast_opensearch_remote_user` and `opencast_opensearch_remote_password` will put
an Nginx virtual host reverse proxy configuration into `/etc/nginx/sites-enabled/`.
- Defaults to `""`
- `opencast_opensearch_remote_host`
- Reverse proxy host name.
- Defaults to `inventory_hostname`
- `opencast_opensearch_remote_port`
- Reverse proxy port
- Defaults to `9243`


## Dependencies

Expand All @@ -47,6 +62,37 @@ Example of how to configure and use the role:
- role: elan.opencast_opensearch
```

## SELinux

On systems with SELinux enabled, the reverse proxy configuration may fail du to SELinux restrictions.
In this case you may want to add this tasks to your playbook:

```yaml
- name: Install SELinux management libraries
ansible.builtin.package:
name:
- python3-libsemanage
- python3-libselinux
when: ansible_selinux is defined and ansible_selinux.status == 'enabled'

- name: Allow reverse-proxy listen on port {{ opencast_opensearch_remote_port }}
community.general.seport:
ports: "{{ opencast_opensearch_remote_port | int }}"
proto: tcp
setype: http_port_t
state: present
when: >-
ansible_selinux is defined and ansible_selinux.status == 'enabled' and
opencast_opensearch_remote_port | int != 443

- name: Allow reverse-proxy connect to other services via http
ansible.posix.seboolean:
name: httpd_can_network_connect
state: true
persistent: true
when: ansible_selinux is defined and ansible_selinux.status == 'enabled'
```

## License
[BSD-3-Clause](LICENSE)

Expand Down
12 changes: 12 additions & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,15 @@ opencast_opensearch_api_port: 9200

# Whether to force the start of the OpenSearch service at the end of this role.
opencast_opensearch_started: false

# Reverse proxy basic auth username
opencast_opensearch_remote_user: ""

# Reverse proxy basic auth password
opencast_opensearch_remote_password: ""

# Reverse proxy hostname
opencast_opensearch_remote_host: "{{ inventory_hostname }}"

# Reverse proxy port
opencast_opensearch_remote_port: 9243
33 changes: 33 additions & 0 deletions files/dummy-tls-crt.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
-----BEGIN CERTIFICATE-----
MIIFozCCA4ugAwIBAgIUQCh76DvcL1n4rdoAT9eOuFnjiA8wDQYJKoZIhvcNAQEL
BQAwYTELMAkGA1UEBhMCREUxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE
CgwTRGVmYXVsdCBDb21wYW55IEx0ZDEdMBsGA1UEAwwUZXhhbXBsZS5vcGVuY2Fz
dC5vcmcwHhcNMTkwMTEwMTcyOTUwWhcNMTkwMTExMTcyOTUwWjBhMQswCQYDVQQG
EwJERTEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENv
bXBhbnkgTHRkMR0wGwYDVQQDDBRleGFtcGxlLm9wZW5jYXN0Lm9yZzCCAiIwDQYJ
KoZIhvcNAQEBBQADggIPADCCAgoCggIBAON56Nb+MxWCoOmW6KG4+VEHBXJftZ/i
JF+u9IDcktrgWWDrDPO5ithrxCAi+78/1kVoOgv4+F9S5LTENfoHCBNlpYrMBIWl
NF5c4FkE1s2JB2NoBz17PVdFoLKU+SSmrf0q+UgCTsNTdZOw96oF1LMNHe7uejpJ
BbsJjaHQquK+YYgcxop2DZ6rGZLktec6wc9jGF8REz+1gvMEm2vg39MVSRba6YLO
mDBQtLyU0z8M25rCPvo4BltXzDuoZ6D0lua9oCCjzH0HQIDpDc7TgJVi1HxHL8Tz
xTgjRTBGnTNBDzyOnti7LnmldRizicFqqgzpdvpbEyYn5QiZRyzJtMwvlSCLYa9F
qyUVxFiAi09piE8iLEY8FTXydMCRfVxq/k9JNsMRgXGaigl1VKkTjMMHhIAXA/7s
9gypbU0uNtGdogI4AL7g8sObLbvjKUXYHbJdiEB0Rq16i8tSZ4/Od5amorXKwsw7
N1Ztiz5TODcZClA4aNOY4+VOvvY1939Qc1gJh//Tx1phkJIAdGvkWkSDz9hHuZGq
whT8MRoznca5feSvPlm/LkqG6sw9GoiKX/OrTqccPx5CNxonxIBG6Putfl9q7hyZ
yvFXXTj8jfqBfJt4PgTmgtqG9RV7KRtoH32a5zISpOLwnjh4sTaUIvCbT/6ZWRB0
TrZs+Fna2DvjAgMBAAGjUzBRMB0GA1UdDgQWBBRUDK218wLs89AZBq7fjuAyBRvT
iDAfBgNVHSMEGDAWgBRUDK218wLs89AZBq7fjuAyBRvTiDAPBgNVHRMBAf8EBTAD
AQH/MA0GCSqGSIb3DQEBCwUAA4ICAQDSYw2WXaUdUKW+UTJvr3KAShRi3Xic3Axg
eFofPYYEJQkn6bvot1NNX/SblCPXcdVWwHe92JnPE+i0xXSOdfcvx8L05FTkvjlE
gw7nSrlBhNZV1kn3mCzkViKXNL9FjBonhG4hUTKOjEOYs6JHQ9y6Izz9CoUVrxAf
T6uHrjgIlcOGNSKbphHpiVD1dvmzZvyjTfJa7PuqIOZG7fRHPZtnSnUKUQx4Ryuk
OiHYQy7rtwlnqCqnuOOOhes+xlFQSOIxN7v3M/AtoHB0IR3d/wRaoA6lwvJIIxE/
9pbBu8e9hqq9O8sSKwIm1YLD41N2TL8gqU3dCGiOJtYkJDAtNigzqaGovrhhTlAl
gK25INuWcNDBmnnq6lKXGgFX8er3mtQZsdhM572TX2ZB4hRSOqyFd6FGr7ypE4V9
uE1n8Ysdwu5TTFn4Nq6k6P1IwUbSfZ2Jmy2djC7wgSBjtzlJxcfP6K40/B538FpT
qOWZJN877PSmT1zjPMBQQo2bo8of7FtrtrgAKwf7wy9VBOyLvkfv65t4uEc/x4Rx
3uS75BH1y5MnnbuFWgeWNYsAMB3WQTSQ0ALM2cycams9V/d/x9G9y0M7nDvW7Q83
9eb2+rX05jUxxzyRObCr5CACChW4kSVLc5oqIuXr30shYegKLuT7xbYsjyLuGx56
iDp1RvjKYQ==
-----END CERTIFICATE-----
52 changes: 52 additions & 0 deletions files/dummy-tls-key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
-----BEGIN PRIVATE KEY-----
MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDjeejW/jMVgqDp
luihuPlRBwVyX7Wf4iRfrvSA3JLa4Flg6wzzuYrYa8QgIvu/P9ZFaDoL+PhfUuS0
xDX6BwgTZaWKzASFpTReXOBZBNbNiQdjaAc9ez1XRaCylPkkpq39KvlIAk7DU3WT
sPeqBdSzDR3u7no6SQW7CY2h0KrivmGIHMaKdg2eqxmS5LXnOsHPYxhfERM/tYLz
BJtr4N/TFUkW2umCzpgwULS8lNM/DNuawj76OAZbV8w7qGeg9JbmvaAgo8x9B0CA
6Q3O04CVYtR8Ry/E88U4I0UwRp0zQQ88jp7Yuy55pXUYs4nBaqoM6Xb6WxMmJ+UI
mUcsybTML5Ugi2GvRaslFcRYgItPaYhPIixGPBU18nTAkX1cav5PSTbDEYFxmooJ
dVSpE4zDB4SAFwP+7PYMqW1NLjbRnaICOAC+4PLDmy274ylF2B2yXYhAdEateovL
UmePzneWpqK1ysLMOzdWbYs+Uzg3GQpQOGjTmOPlTr72Nfd/UHNYCYf/08daYZCS
AHRr5FpEg8/YR7mRqsIU/DEaM53GuX3krz5Zvy5KhurMPRqIil/zq06nHD8eQjca
J8SARuj7rX5fau4cmcrxV104/I36gXybeD4E5oLahvUVeykbaB99mucyEqTi8J44
eLE2lCLwm0/+mVkQdE62bPhZ2tg74wIDAQABAoICAQCXhItwMQ/Lwx/1l5xKpJAE
xb1+CnxLC/GYfkvETafP/OHr6YTODweJ0nZnxYWURSwvPRZ1BRhDPk6yjYM6kFZz
vSAADJbygjEYrZqOEOgXLa/rKc6wyBb6u5kneo1dOVzpJie3LDpUZpIJlzXQXWPp
A9KtZNGrYxpbFCjv4LMCpzcF18zzS2EVD/jP3GHBrGSOA/6mzBPbOscHokj4GWhd
DG+LtrMVexDqFcfdWPBArgrU0Y/rUUgCrb+O+URVdLXS6fnv48sAeMUhWJrm6gBb
AOJyCWSrNohmNTAP0OlCy5IfjwwFZuC1DF2r32Lhn2+3fAbRCbr+jlJDYP2EurIe
kgh9j3UH7gYEaFAx1HGhp/9bZKQv5xiIpbCUshyinix5MUujZ5WY2c1P2ReCOTXb
psH6hf1H5M4stZlk8uBp2cVHLb6CrVfxtuzPAYbKtUpdEdw9QpfMYUMxkmZtwi1O
TuJ7sfpJukTsEZNNu9BnP6WU2Q3MuRoMKYLpqDU1tQitYXgvyjnf5sxsn4qWy+ap
k0pzFkIxl0kX81rH7TtSJQyGKwfGtNIOFA8GnjD39vDy7BbLJ4OMtlwoQVhU3bk8
NUHQRQEiEo49Z5E0AiUnSpcuuo+6WcS2i30rBfeyVm48lBXRtuJJrHGSPY23O58K
8Dfzbc5O+84z2irWkDJjWQKCAQEA9YAYIiPN9c45bJw3+W7/v14p3qAFMrQCZZKC
EU8Ht177pa4uE59hSDXZautONiHssOwdYKKOGNAf4I87WvuAQZNfjAv/521/Zqli
82el0R9jfEhpNFMHvRVIHVoXuAuAPzF96sPvgHc94nh/yw5x73mWm67Qt2wh8U/i
uQAW7q2s1Td9uD9ot2EUawcvP6sSx+OKnXb/1MpwaGZu14yV8YorUceWyVB8tYHw
6AtuVOo6lek+VdxztI9tHCHq0wDkkUxVf9WSIlDAtEsDXL7PznYAYz7E/4pUfDfO
holeTzGRuMDMQY1BtVuMvRVm5BHdBlAMmzhu+DRbyofl5nUXdQKCAQEA7TR5dcVC
HCUV8P4UCGUnF0Q0beW6992uaKnofSiq22x5XbTsummrmQAKfoTx+zDJO8eFsaYw
rVxDATxaz+8L73V5cdLh3nDbnSEmpaeS7Pp1fW9ZDdoAnu3pzs5m7joepfnVKARI
XiuwSFDzzD4XDZBMxsDQt4taywQmIua61BpTRC+o9/0aVKafvoR8xJoM2lp7akuI
ChYecwRWqlsZByergRK0RbrJvdbhmZ3aewe1AfCKneSsaDMa5SA0XGU/1fIAfsoI
hkP8O8uBJ/T442qTKqJXB1SR4wzyxVc5Ip0yjcOtVFIWzBxFu2jVQcpTIKHtxY+K
R09sXEvvzKry9wKCAQA4RapCeQ6Gn0SOXqh95jF8/ep++xL18kjyW0ixCvprz7vC
2E/7c3brBFzXoyQESHZmf1ikg94qVdpYsLwcOLXHUi5+fWmk9HZVY9IolMNvUdCN
9lMXCUkm0C/9el8hcpFs6r1ACLVnLu3icVhphOAc0jPxb3qr8H8/Pt5rJVgcUXbi
UJvilbY9AmWZusXbxCzD4KYvPc2aSuTFKWWSxsi/2rnfPu6TKn3LZQOBTM13bVEM
d7AwIh3rb0zFPAkFYJkDrQmUCbI7Z2MkcGVO5vXfDzE7jnG9WUnQR0JxmB8j6+rI
/HhVNjmvhlKWLMeu02FkRwj8s0zMW8QGgmvyDTjZAoIBAH9nL9WRnXCAesh1r0zT
B6v3djGQsltvNb4BhF20+g/gs08hXgTBvOjwnLJXtaC1E2CIScag/IQgidygDiag
vkhfUFtSaP6Qn2RF6fwPhVrDK1ez9qD59ltmba4mLiLGFLAQ/+v+YOAzlvtAf7Gz
p64hUxttdK0grCNelx0n0DEb8p0s/BQ2XW4aELLDdkAifcTJ1H/DEc5ZEwGz0tit
FURCiltJMIpDSRgt0f4wSqjJ+u6Pw+QKbo+I42ktYvI9b4v570oqOWnkGhYDt9s+
OG/tTh4YE6ZcRf8tdTeJIab1x7Fc6Dvh21zF0q5WIDS19vAQCSWTczHZ9tmb77B+
IQECggEBALwKAurIOP5VTvqWYwPs4KI8Nt05pFG9EO3Gi5pFxfyUfdCUAkb93/L7
mWZk1KHX3lx104c5KNWBHb9l1WraWb4dTNrpJfkPGao4rkJMAGy8GnYRB0ILYl4n
EFU5qwRYc7VjezCgRtN4HotOI7IZMU9A1NH46ueO0xij9zGJB2W2hbtzhOlkgtHr
Mpj54Jc4mftLup9oWw1pwm74rvu9LOLWNQNcfSRGnlypMIKQNl1PyPJ8kqTyFHtO
h9JmUedeCLx3NfUwmv43t/zxPqUvR9/jTFO7CqnbirnAKdwP5T1VzS7qRdXeoCAc
d4+15XFG9j1pbtpoJBt5+Z+au42FdDw=
-----END PRIVATE KEY-----
15 changes: 15 additions & 0 deletions handlers/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,18 @@
ansible.builtin.systemd:
name: opensearch
state: restarted

- name: Gather service facts
ansible.builtin.service_facts:
listen: Reload nginx

- name: Reload nginx if service exists
ansible.builtin.systemd:
name: nginx
state: reloaded
when: >-
ansible_facts['services'].values()
| selectattr('name', 'equalto', 'nginx.service')
| selectattr('state', 'equalto', 'running')
| length > 0
listen: Reload nginx
2 changes: 2 additions & 0 deletions molecule/default/converge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
opencast_version_major: 17
opencast_repository_enabled_release: true
opencast_opensearch_heap_size: 100m
opencast_opensearch_remote_user: opencast
opencast_opensearch_remote_password: opensearchpassword
tasks:
- name: Apply opencast_opensearch role
ansible.builtin.include_role:
Expand Down
6 changes: 6 additions & 0 deletions tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,9 @@
name: opensearch
state: started
when: opencast_opensearch_started | bool

- name: Include reverse proxy configuration tasks
ansible.builtin.include_tasks: nginx_reverse_proxy.yml
when: >-
opencast_opensearch_remote_user != '' and
opencast_opensearch_remote_password != ''
47 changes: 47 additions & 0 deletions tasks/nginx_reverse_proxy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
- name: Create nginx directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: root
group: root
mode: "0755"
loop:
- /etc/nginx/sites-enabled
- /etc/nginx/ssl

- name: Install Passlib
ansible.builtin.package:
name: python3-passlib

- name: Install dummy tls certificate
ansible.builtin.copy:
src: dummy-tls-{{ item }}.pem
dest: /etc/nginx/ssl/{{ opencast_opensearch_remote_host }}.{{ item }}
owner: root
group: root
mode: '0400'
force: false
notify: Reload nginx
loop:
- key
- crt

- name: Create opensearch htpasswd
community.general.htpasswd:
path: /etc/nginx/opensearch_htpasswd
owner: root
group: "root"
mode: "0640"
name: "{{ opencast_opensearch_remote_user }}"
password: "{{ opencast_opensearch_remote_password }}"
notify: Reload nginx

- name: Create Nginx virtual host
ansible.builtin.template:
src: nginx-vhost.conf
dest: /etc/nginx/sites-enabled/opensearch.conf
owner: root
group: root
mode: "0644"
notify: Reload nginx
45 changes: 45 additions & 0 deletions templates/nginx-vhost.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
server {
listen {{ opencast_opensearch_remote_port | int }} ssl http2;
listen [::]:{{ opencast_opensearch_remote_port | int }} ssl http2;
server_name {{ opencast_opensearch_remote_host }};

ssl_certificate_key /etc/nginx/ssl/{{ opencast_opensearch_remote_host }}.key;
ssl_certificate /etc/nginx/ssl/{{ opencast_opensearch_remote_host }}.crt;

# Additional TLS related Nginx options
include /etc/nginx/conf.d/tls.conf;

# Access log settings.
access_log off;
#access_log /var/log/nginx/opensearch_access.log;

# Accept large ingests
client_max_body_size 0;

# Proxy configuration for Opencast
location / {
auth_basic "Authentication required";
auth_basic_user_file /etc/nginx/opensearch_htpasswd;

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_set_header X-Forwarded-SSL "on";

proxy_pass http://{{ opencast_opensearch_api_host if opencast_opensearch_api_host != "0.0.0.0" else "127.0.0.1" }}:{{ opencast_opensearch_api_port | int }};

# Do not buffer responses
proxy_buffering off;

# Do not buffer requests
proxy_request_buffering off;

# Timeout for reading a response from the proxied server (OpenSearch)
proxy_read_timeout 600;
# Timeout for transmitting a request to the proxied server (OpenSearch)
proxy_send_timeout 300;
# Timeout for transmitting a response to the client
send_timeout 300;
}
}