nginx/ansible-role-nginx-config

Question - QUIC config

Closed this issue ยท 5 comments

I'm trying to setup QUIC support as described here.
So far I encounter several problems:

  1. I cannot add line "listen 443 quic reuseport;" to output nginx conf in server section. Relevant part from playbook:
 - port: 443
   quic: true
   reuseport: true

Will result in nginx conf :

listen 443 reuseport;

As far as I understand quic is not supported yet, is there any workaround?

  1. I have problems with adding Alt-Svc 'h3=":8443"; ma=86400'; header. When I run my playbook with molecule I receive next error:
RUNNING HANDLER [nginxinc.nginx_config : (Handler - NGINX Config) Print NGINX error if syntax check fails] ***
fatal: [ubuntu-jammy]: FAILED! => {
    "config_check['stderr_lines']": [
        "nginx: [emerg] unknown directive \"ma=86400\" in /etc/nginx/conf.d/default.conf:21",
        "nginx: configuration file /etc/nginx/nginx.conf test failed"
    ],
    "failed_when_result": true
}

Nevertheless output nginx conf has correct header line: add_header Alt-Svc h3=":443"; ma=86400;. Am I doing something wrong here so error emerges?

My playbook:

---
- name: Install NGINX and configure a simple reverse proxy in front of two web servers
  hosts: all
  tasks:
    - name: Install NGINX
      ansible.builtin.include_role:
        name: nginxinc.nginx

    - name: Configure NGINX
      ansible.builtin.include_role:
        name: nginxinc.nginx_config
      vars:
        nginx_config_debug_output: true
        nginx_config_http_template_enable: true
        nginx_config_http_template:
          - config:
              upstreams:
                - name: backend
                  least_conn: true
                  servers:
                    - address: 10.100.0.3:8080
              servers:
                - core:
                    listen:
                      - port: 80
                      - port: 443
                        quic: true
                        reuseport: true
                    server_name: mydomain.com
                  log:
                    access:
                      - path: /var/log/nginx/access.log
                        format: main
                  locations:
                    - location: /
                      proxy:
                        pass: http://backend/
                      headers:
                        add_headers:
                          - name: Alt-Svc
                            value: 'h3=":443"; ma=86400'

Nginx output default.conf:

upstream backend {
    server 10.100.0.3:8080;
    least_conn;
}

server {
    listen 80;
    listen 443 reuseport;
    server_name mydomain.com;

    access_log /var/log/nginx/access.log main;

    location / {
        proxy_pass http://backend/;

        add_header Host $host;
        add_header Alt-Svc h3=":443"; ma=86400;


    }
}

I cannot add line "listen 443 quic reuseport;" to output nginx conf in server section. Relevant part from playbook:

 - port: 443
   quic: true
   reuseport: true

Will result in nginx conf :

listen 443 reuseport;

As far as I understand quic is not supported yet, is there any workaround?

quic is indeed not implemented yet. You could get around it either pushing a pre-existing config file (see https://github.com/nginxinc/ansible-role-nginx-config/blob/main/defaults/main/upload.yml) or using the custom_directives parameter inside the relevant server block (https://github.com/nginxinc/ansible-role-nginx-config/blob/main/defaults/main/template.yml#L699).

I have problems with adding Alt-Svc 'h3=":8443"; ma=86400'; header. When I run my playbook with molecule I receive next error:

RUNNING HANDLER [nginxinc.nginx_config : (Handler - NGINX Config) Print NGINX error if syntax check fails] ***
fatal: [ubuntu-jammy]: FAILED! => {
    "config_check['stderr_lines']": [
        "nginx: [emerg] unknown directive \"ma=86400\" in /etc/nginx/conf.d/default.conf:21",
        "nginx: configuration file /etc/nginx/nginx.conf test failed"
    ],
    "failed_when_result": true
}

Nevertheless output nginx conf has correct header line: add_header Alt-Svc h3=":443"; ma=86400;. Am I doing something wrong here so error emerges?

The template is working as expected. The issue is that the way you are defining it, you have two unquoted semi-colons (;). NGINX treats the semi-colon as a directive termination statement, and thus bugs out when it finds two back to back without a directive in-between. The correct NGINX conf would be add_header Alt-Svc 'h3=":443"; ma=86400;'. You might need to escape the single quotes and to make sure that the body of the Alt-Svc header gets correctly parsed by Jinja2 (try something like value: ''h3=":443"; ma=86400'')

oxpa commented

@alex1704 i'm looking to submit a pull request next week. So if this is not urgent - we'll have something for you.

@alessfg thanks for directions.
@oxpa thanks, it is not urgent.

Just for future reference, here is config excerpt that applied custom_directives workaround:

nginx_config_http_template:
  - config:
      upstreams:
        - name: backend
          least_conn: true
          servers:
            - address: 10.10.0.2

      servers:
        - core:
            listen:
              - port: 443
                ssl: true
            server_name: "{{ cert_domain_name }}"
          custom_directives:
            - listen 443 quic reuseport;
          ssl:
            certificate: "{{ cert_fullchain_path }}"
            certificate_key: "{{ cert_key_path }}"
          log:
            access:
              - path: "/var/log/nginx/access.log"
                format: main
          locations:
            - location: /
              custom_directives:
                - add_header Alt-Svc 'h3=":443"; ma=86400';
              proxy:
                pass: http://backend/
                set_header:
                  - field: Host
                    value: $server_name

HTTP3/QUIC have been implemented as of #353 ๐Ÿ˜„